summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GNUmakefile232
-rw-r--r--src/Makefile7
-rw-r--r--src/compat52.h178
-rw-r--r--src/openssl.auxlib.lua21
-rw-r--r--src/openssl.bignum.lua3
-rw-r--r--src/openssl.c10357
-rw-r--r--src/openssl.cipher.lua3
-rw-r--r--src/openssl.des.lua3
-rw-r--r--src/openssl.digest.lua3
-rw-r--r--src/openssl.hmac.lua3
-rw-r--r--src/openssl.lua1
-rw-r--r--src/openssl.ocsp.basic.lua3
-rw-r--r--src/openssl.ocsp.response.lua3
-rw-r--r--src/openssl.pkcs12.lua1
-rw-r--r--src/openssl.pkey.lua4
-rw-r--r--src/openssl.pubkey.lua2
-rw-r--r--src/openssl.rand.lua3
-rw-r--r--src/openssl.ssl.context.lua16
-rw-r--r--src/openssl.ssl.lua3
-rw-r--r--src/openssl.x509.altname.lua14
-rw-r--r--src/openssl.x509.chain.lua3
-rw-r--r--src/openssl.x509.crl.lua1
-rw-r--r--src/openssl.x509.csr.lua1
-rw-r--r--src/openssl.x509.extension.lua1
-rw-r--r--src/openssl.x509.lua3
-rw-r--r--src/openssl.x509.name.lua14
-rw-r--r--src/openssl.x509.store.lua3
-rw-r--r--src/openssl.x509.verify_param.lua1
28 files changed, 10887 insertions, 0 deletions
diff --git a/src/GNUmakefile b/src/GNUmakefile
new file mode 100644
index 0000000..4bf5f8d
--- /dev/null
+++ b/src/GNUmakefile
@@ -0,0 +1,232 @@
1# non-recursive prologue
2sp := $(sp).x
3dirstack_$(sp) := $(d)
4d := $(abspath $(lastword $(MAKEFILE_LIST))/..)
5
6ifeq ($(origin GUARD_$(d)), undefined)
7GUARD_$(d) := 1
8
9
10#
11# E N V I R O N M E N T C O N F I G U R A T I O N
12#
13include $(d)/../GNUmakefile
14
15
16#
17# C O M P I L A T I O N F L A G S
18#
19CPPFLAGS_$(d) = $(ALL_CPPFLAGS) -DHAVE_CONFIG_H
20CFLAGS_$(d) = $(ALL_CFLAGS)
21SOFLAGS_$(d) = $(ALL_SOFLAGS)
22LDFLAGS_$(d) = $(ALL_LDFLAGS)
23LIBS_$(d) = $(ALL_LIBS)
24
25#
26# C O M P I L A T I O N R U L E S
27#
28OBJS_$(d) = openssl.o
29
30$(d)/config.h: $(abspath $(d)/..)/config.h
31 $(CP) $< $@
32
33define BUILD_$(d)
34
35$$(d)/$(1)/openssl.so: $$(addprefix $$(d)/$(1)/, $$(OBJS_$(d)))
36 $$(CC) -o $$@ $$^ $$(SOFLAGS_$$(abspath $$(@D)/..)) $$(LDFLAGS_$$(abspath $$(@D)/..)) $$(LIBS_$$(abspath $$(@D)/..))
37
38$$(d)/$(1)/%.o: $$(d)/%.c $$(d)/compat52.h $$(d)/config.h
39 $$(MKDIR) -p $$(@D)
40 $$(CC) $$(CFLAGS_$$(<D)) $$(ALL_LUA$(subst .,,$(1))_CPPFLAGS) $$(CPPFLAGS_$$(<D)) -c -o $$@ $$<
41
42.SECONDARY: liblua$(1)-openssl openssl$(1) openssl
43
44liblua$(1)-openssl openssl$(1) openssl: $$(d)/$(1)/openssl.so
45
46endef # BUILD_$(d)
47
48$(eval $(call BUILD_$(d),5.1))
49$(eval $(call BUILD_$(d),5.2))
50$(eval $(call BUILD_$(d),5.3))
51
52ifneq "$(filter $(abspath $(d)/..)/%, $(abspath $(firstword $(MAKEFILE_LIST))))" ""
53.SECONDARY: all all5.1 all5.2 all5.3
54
55all5.1: liblua5.1-openssl
56all5.2: liblua5.2-openssl
57all5.3: liblua5.3-openssl
58all: $(foreach API,$(strip $(LUA_APIS)),all$(API))
59
60endif
61
62
63#
64# I N S T A L L & U N I N S T A L L R U L E S
65#
66define INSTALL_$(d)
67
68MODS$(1)_$(d) = \
69 $$(DESTDIR)$(2)/_openssl.so \
70 $$(DESTDIR)$(3)/openssl.lua \
71 $$(DESTDIR)$(3)/openssl/auxlib.lua \
72 $$(DESTDIR)$(3)/openssl/bignum.lua \
73 $$(DESTDIR)$(3)/openssl/ocsp/basic.lua \
74 $$(DESTDIR)$(3)/openssl/ocsp/response.lua \
75 $$(DESTDIR)$(3)/openssl/pkey.lua \
76 $$(DESTDIR)$(3)/openssl/pubkey.lua \
77 $$(DESTDIR)$(3)/openssl/x509.lua \
78 $$(DESTDIR)$(3)/openssl/x509/name.lua \
79 $$(DESTDIR)$(3)/openssl/x509/altname.lua \
80 $$(DESTDIR)$(3)/openssl/x509/chain.lua \
81 $$(DESTDIR)$(3)/openssl/x509/crl.lua \
82 $$(DESTDIR)$(3)/openssl/x509/csr.lua \
83 $$(DESTDIR)$(3)/openssl/x509/extension.lua \
84 $$(DESTDIR)$(3)/openssl/x509/store.lua \
85 $$(DESTDIR)$(3)/openssl/x509/verify_param.lua \
86 $$(DESTDIR)$(3)/openssl/pkcs12.lua \
87 $$(DESTDIR)$(3)/openssl/ssl/context.lua \
88 $$(DESTDIR)$(3)/openssl/ssl.lua \
89 $$(DESTDIR)$(3)/openssl/digest.lua \
90 $$(DESTDIR)$(3)/openssl/hmac.lua \
91 $$(DESTDIR)$(3)/openssl/cipher.lua \
92 $$(DESTDIR)$(3)/openssl/rand.lua \
93 $$(DESTDIR)$(3)/openssl/des.lua
94
95.SECONDARY: liblua$(1)-openssl-install openssl$(1)-install
96
97liblua$(1)-openssl-install openssl$(1)-install: $$(MODS$(1)_$$(d))
98
99$$(DESTDIR)$(2)/_openssl.so: $$(d)/$(1)/openssl.so
100 $$(MKDIR) -p $$(@D)
101 $$(CP) -p $$< $$@
102
103$$(DESTDIR)$(3)/%.lua: $$(d)/%.lua
104 $$(LUAC$(subst .,,$(1))) -p $$<
105 $$(MKDIR) -p $$(@D)
106 $$(CP) -p $$< $$@
107
108$$(DESTDIR)$(3)/openssl/%.lua: $$(d)/openssl.%.lua
109 $$(LUAC$(subst .,,$(1))) -p $$<
110 $$(MKDIR) -p $$(@D)
111 $$(CP) -p $$< $$@
112
113$$(DESTDIR)$(3)/openssl/ocsp/%.lua: $$(d)/ocsp.%.lua
114 $$(LUAC$(subst .,,$(1))) -p $$<
115 $$(MKDIR) -p $$(@D)
116 $$(CP) -p $$< $$@
117
118$$(DESTDIR)$(3)/openssl/x509/%.lua: $$(d)/x509.%.lua
119 $$(LUAC$(subst .,,$(1))) -p $$<
120 $$(MKDIR) -p $$(@D)
121 $$(CP) -p $$< $$@
122
123$$(DESTDIR)$(3)/openssl/ssl/%.lua: $$(d)/ssl.%.lua
124 $$(LUAC$(subst .,,$(1))) -p $$<
125 $$(MKDIR) -p $$(@D)
126 $$(CP) -p $$< $$@
127
128liblua$(1)-openssl-install openssl$(1)-install: $$(MODS$(1)_$$(d))
129
130.PHONY: liblua$(1)-openssl-uninstall openssl$(1)-uninstall
131
132liblua$(1)-openssl-uninstall openssl$(1)-uninstall:
133 $$(RM) -f $$(MODS$(1)_$(d))
134 -$$(RMDIR) $$(DESTDIR)$(3)/openssl/ocsp
135 -$$(RMDIR) $$(DESTDIR)$(3)/openssl/x509
136 -$$(RMDIR) $$(DESTDIR)$(3)/openssl/ssl
137 -$$(RMDIR) $$(DESTDIR)$(3)/openssl
138
139endef # INSTALL_$(d)
140
141$(eval $(call INSTALL_$(d),5.1,$$(lua51cpath),$$(lua51path)))
142$(eval $(call INSTALL_$(d),5.2,$$(lua52cpath),$$(lua52path)))
143$(eval $(call INSTALL_$(d),5.3,$$(lua53cpath),$$(lua53path)))
144
145ifneq "$(filter $(abspath $(d)/..)/%, $(abspath $(firstword $(MAKEFILE_LIST))))" ""
146
147.SECONDARY: install5.1 install5.2 install5.3 install
148
149install5.1: liblua5.1-openssl-install
150install5.2: liblua5.2-openssl-install
151install5.3: liblua5.3-openssl-install
152install: $(foreach API,$(strip $(LUA_APIS)),install$(API))
153
154.PHONY: uninstall5.1 uninstall5.2 uninstall5.3 uninstall
155
156uninstall5.1: liblua5.1-openssl-uninstall
157uninstall5.2: liblua5.2-openssl-uninstall
158uninstall5.3: liblua5.3-openssl-uninstall
159uninstall: $(foreach API,$(strip $(LUA_APIS)),uninstall$(API))
160
161endif
162
163
164#
165# C L E A N R U L E S
166#
167.PHONY: $(d)/clean $(d)/clean~ clean clean~
168
169$(d)/clean:
170 $(RM) -fr $(@D)/config.h $(@D)/*.dSYM $(@D)/5.1 $(@D)/5.2 $(@D)/5.3
171
172$(d)/clean~: $(d)/clean
173 $(RM) -f $(@D)/*~
174
175clean: $(d)/clean
176
177clean~: $(d)/clean~
178
179
180#
181# H E L P R U L E S
182#
183.PHONY: $(d)/help help
184
185$(d)/help:
186 @echo
187 @echo "src/ targets:"
188 @echo ""
189 @echo " all - build all API targets"
190 @echo " all5.1 - build 5.1/openssl.so"
191 @echo " all5.2 - build 5.2/openssl.so"
192 @echo " all5.3 - build 5.3/openssl.so"
193 @echo " install - install all API targets"
194 @echo " install5.1 - install openssl Lua 5.1 modules"
195 @echo " install5.2 - install openssl Lua 5.2 modules"
196 @echo " install5.3 - install openssl Lua 5.3 modules"
197 @echo " uninstall - uninstall all API targets"
198 @echo "uninstall5.1 - uninstall openssl Lua 5.1 modules"
199 @echo "uninstall5.2 - uninstall openssl Lua 5.2 modules"
200 @echo "uninstall5.3 - uninstall openssl Lua 5.3 modules"
201 @echo " clean - rm binary targets, object files, debugging symbols, etc"
202 @echo " clean~ - clean + rm *~"
203 @echo " help - echo this help message"
204 @echo ""
205 @echo "Some important Make variables:"
206 @echo ""
207 @echo ' LUA_APIS - default Lua APIs to target ($(LUA_APIS))'
208 @echo " prefix - path to install root ($(value prefix))"
209 @echo ' lua51path - install path for Lua 5.1 modules ($(value lua51path))'
210 @echo 'lua51cpath - install path for Lua 5.1 C modules ($(value lua51cpath))'
211 @echo ' lua52path - install path for Lua 5.2 modules ($(value lua52path))'
212 @echo 'lua52cpath - install path for Lua 5.2 C modules ($(value lua52cpath))'
213 @echo ' lua53path - install path for Lua 5.3 modules ($(value lua53path))'
214 @echo 'lua53cpath - install path for Lua 5.3 C modules ($(value lua53cpath))'
215 @echo ""
216 @echo 'LUA51_CPPFLAGS - cpp flags for Lua 5.1 headers ($(LUA51_CPPFLAGS))'
217 @echo 'LUA52_CPPFLAGS - cpp flags for Lua 5.2 headers ($(LUA52_CPPFLAGS))'
218 @echo 'LUA53_CPPFLAGS - cpp flags for Lua 5.3 headers ($(LUA53_CPPFLAGS))'
219 @echo ""
220 @echo "(NOTE: all the common GNU-style paths are supported, including"
221 @echo "prefix, bindir, libdir, datadir, includedir, and DESTDIR.)"
222 @echo ""
223 @echo "Report bugs to <william@25thandClement.com>"
224
225help: $(d)/help
226
227
228endif # include guard
229
230# non-recursive epilogue
231d := $(dirstack_$(sp))
232sp := $(basename $(sp))
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..d0f0d47
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,7 @@
1.POSIX:
2
3all:
4 +gmake -f GNUmakefile all
5
6.DEFAULT:
7 +gmake -f GNUmakefile $<
diff --git a/src/compat52.h b/src/compat52.h
new file mode 100644
index 0000000..9b0a48e
--- /dev/null
+++ b/src/compat52.h
@@ -0,0 +1,178 @@
1/* ==========================================================================
2 * compat52.h - Routines for Lua 5.2 compatibility
3 * --------------------------------------------------------------------------
4 * Copyright (c) 2012 William Ahern
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to permit
11 * persons to whom the Software is furnished to do so, subject to the
12 * following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
20 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * ==========================================================================
25 */
26
27
28#if LUA_VERSION_NUM < 503
29
30#define lua_getfield(L, i, f) (lua_getfield(L, (i), (f)), lua_type(L, -1))
31
32static int lua_isinteger(lua_State *L, int index) {
33 if (lua_type(L, index) == LUA_TNUMBER) {
34 lua_Number n = lua_tonumber(L, index);
35 lua_Integer i = lua_tointeger(L, index);
36 if (i == n)
37 return 1;
38 }
39 return 0;
40}
41
42#endif
43
44#if LUA_VERSION_NUM < 502
45
46#define LUA_OK 0
47
48
49static void luaL_setmetatable(lua_State *L, const char *tname) {
50 luaL_getmetatable(L, tname);
51 lua_setmetatable(L, -2);
52} /* luaL_setmetatable() */
53
54
55static int lua_absindex(lua_State *L, int idx) {
56 return (idx > 0 || idx <= LUA_REGISTRYINDEX)? idx : lua_gettop(L) + idx + 1;
57} /* lua_absindex() */
58
59
60static void *luaL_testudata(lua_State *L, int arg, const char *tname) {
61 void *p = lua_touserdata(L, arg);
62 int eq;
63
64 if (!p || !lua_getmetatable(L, arg))
65 return 0;
66
67 luaL_getmetatable(L, tname);
68 eq = lua_rawequal(L, -2, -1);
69 lua_pop(L, 2);
70
71 return (eq)? p : 0;
72} /* luaL_testudate() */
73
74
75static void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) {
76 int i, t = lua_absindex(L, -1 - nup);
77
78 for (; l->name; l++) {
79 for (i = 0; i < nup; i++)
80 lua_pushvalue(L, -nup);
81 lua_pushcclosure(L, l->func, nup);
82 lua_setfield(L, t, l->name);
83 }
84
85 lua_pop(L, nup);
86} /* luaL_setfuncs() */
87
88
89#define luaL_newlibtable(L, l) \
90 lua_createtable(L, 0, (sizeof (l) / sizeof *(l)) - 1)
91
92#define luaL_newlib(L, l) \
93 (luaL_newlibtable((L), (l)), luaL_setfuncs((L), (l), 0))
94
95
96static void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int glb) {
97 lua_pushcfunction(L, openf);
98 lua_pushstring(L, modname);
99 lua_call(L, 1, 1);
100
101 lua_getglobal(L, "package");
102 lua_getfield(L, -1, "loaded");
103 lua_pushvalue(L, -3);
104 lua_setfield(L, -2, modname);
105
106 lua_pop(L, 2);
107
108 if (glb) {
109 lua_pushvalue(L, -1);
110 lua_setglobal(L, modname);
111 }
112} /* luaL_requiref() */
113
114
115#define lua_resume(L, from, nargs) lua_resume((L), (nargs))
116
117
118static void lua_rawgetp(lua_State *L, int index, const void *p) {
119 index = lua_absindex(L, index);
120 lua_pushlightuserdata(L, (void *)p);
121 lua_rawget(L, index);
122} /* lua_rawgetp() */
123
124static void lua_rawsetp(lua_State *L, int index, const void *p) {
125 index = lua_absindex(L, index);
126 lua_pushlightuserdata(L, (void *)p);
127 lua_pushvalue(L, -2);
128 lua_rawset(L, index);
129 lua_pop(L, 1);
130} /* lua_rawsetp() */
131
132
133#ifndef LUA_UNSIGNED
134#define LUA_UNSIGNED unsigned
135#endif
136
137typedef LUA_UNSIGNED lua_Unsigned;
138
139
140static void lua_pushunsigned(lua_State *L, lua_Unsigned n) {
141 lua_pushnumber(L, (lua_Number)n);
142} /* lua_pushunsigned() */
143
144static lua_Unsigned luaL_checkunsigned(lua_State *L, int arg) {
145 return (lua_Unsigned)luaL_checknumber(L, arg);
146} /* luaL_checkunsigned() */
147
148
149static lua_Unsigned luaL_optunsigned(lua_State *L, int arg, lua_Unsigned def) {
150 return (lua_Unsigned)luaL_optnumber(L, arg, (lua_Number)def);
151} /* luaL_optunsigned() */
152
153
154#ifndef LUA_FILEHANDLE /* Not defined by earlier LuaJIT releases */
155#define LUA_FILEHANDLE "FILE*"
156#endif
157
158/*
159 * Lua 5.1 userdata is a simple FILE *, while LuaJIT is a struct with the
160 * first member a FILE *, similar to Lua 5.2.
161 */
162typedef struct luaL_Stream {
163 FILE *f;
164} luaL_Stream;
165
166
167#define lua_rawlen(...) lua_objlen(__VA_ARGS__)
168
169
170#define lua_pushstring(...) lua52_pushstring(__VA_ARGS__)
171
172static const char *lua52_pushstring(lua_State *L, const char *s) {
173 (lua_pushstring)(L, s);
174 return lua_tostring(L, -1);
175} /* lua52_pushstring() */
176
177
178#endif /* LUA_VERSION_NUM < 502 */
diff --git a/src/openssl.auxlib.lua b/src/openssl.auxlib.lua
new file mode 100644
index 0000000..4f00c25
--- /dev/null
+++ b/src/openssl.auxlib.lua
@@ -0,0 +1,21 @@
1local auxlib = {}
2
3if _VERSION == "Lua 5.1" then
4 local _pairs = pairs
5
6 function auxlib.pairs(t)
7 if type(t) == "userdata" then
8 local mt = getmetatable(t)
9
10 if mt and mt.__pairs then
11 return mt.__pairs(t)
12 else
13 return _pairs(t)
14 end
15 end
16 end
17else
18 auxlib.pairs = pairs
19end
20
21return auxlib
diff --git a/src/openssl.bignum.lua b/src/openssl.bignum.lua
new file mode 100644
index 0000000..3090a68
--- /dev/null
+++ b/src/openssl.bignum.lua
@@ -0,0 +1,3 @@
1local bignum = require"_openssl.bignum"
2
3return bignum
diff --git a/src/openssl.c b/src/openssl.c
new file mode 100644
index 0000000..50ce7d3
--- /dev/null
+++ b/src/openssl.c
@@ -0,0 +1,10357 @@
1/* ==========================================================================
2 * openssl.c - Lua OpenSSL
3 * --------------------------------------------------------------------------
4 * Copyright (c) 2012-2015 William Ahern
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to permit
11 * persons to whom the Software is furnished to do so, subject to the
12 * following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
20 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * ==========================================================================
25 */
26#if HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30#include <limits.h> /* INT_MAX INT_MIN LLONG_MAX LLONG_MIN UCHAR_MAX ULLONG_MAX */
31#include <stdint.h> /* uintptr_t */
32#include <string.h> /* memset(3) strerror_r(3) */
33#include <strings.h> /* strcasecmp(3) */
34#include <math.h> /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */
35#include <time.h> /* struct tm time_t strptime(3) time(2) */
36#include <ctype.h> /* isdigit(3), isxdigit(3), tolower(3) */
37#include <errno.h> /* ENOMEM ENOTSUP EOVERFLOW errno */
38#include <assert.h> /* assert */
39
40#include <sys/types.h> /* ssize_t pid_t */
41#include <sys/time.h> /* struct timeval gettimeofday(2) */
42#include <sys/stat.h> /* struct stat stat(2) */
43#include <sys/socket.h> /* AF_INET AF_INET6 */
44#include <sys/resource.h> /* RUSAGE_SELF struct rusage getrusage(2) */
45#include <sys/utsname.h> /* struct utsname uname(3) */
46#include <fcntl.h> /* O_RDONLY O_CLOEXEC open(2) */
47#include <unistd.h> /* close(2) getpid(2) */
48#include <netinet/in.h> /* struct in_addr struct in6_addr */
49#include <arpa/inet.h> /* inet_pton(3) */
50#include <pthread.h> /* pthread_mutex_init(3) pthread_mutex_lock(3) pthread_mutex_unlock(3) */
51#include <dlfcn.h> /* dladdr(3) dlopen(3) */
52
53#if __APPLE__
54#include <mach/mach_time.h> /* mach_absolute_time() */
55#endif
56
57#include <openssl/opensslconf.h>
58#include <openssl/opensslv.h>
59#include <openssl/err.h>
60#include <openssl/bn.h>
61#include <openssl/asn1.h>
62#include <openssl/x509.h>
63#include <openssl/x509_vfy.h>
64#include <openssl/x509v3.h>
65#include <openssl/pkcs12.h>
66#include <openssl/evp.h>
67#include <openssl/pem.h>
68#include <openssl/ssl.h>
69#include <openssl/hmac.h>
70#include <openssl/rand.h>
71#include <openssl/des.h>
72#include <openssl/ocsp.h>
73
74#include <lua.h>
75#include <lualib.h>
76#include <lauxlib.h>
77
78#include "compat52.h"
79
80#define GNUC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p))
81#define GNUC_PREREQ(M, m, p) (__GNUC__ > 0 && GNUC_2VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) >= GNUC_2VER((M), (m), (p)))
82
83#define MSC_2VER(M, m, p) ((((M) + 6) * 10000000) + ((m) * 1000000) + (p))
84#define MSC_PREREQ(M, m, p) (_MSC_FULL_VER > 0 && _MSC_FULL_VER >= MSC_2VER((M), (m), (p)))
85
86#define OPENSSL_PREREQ(M, m, p) \
87 (OPENSSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)) && !defined LIBRESSL_VERSION_NUMBER)
88
89#define LIBRESSL_PREREQ(M, m, p) \
90 (LIBRESSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)))
91
92#ifndef __has_builtin
93#define __has_builtin(x) 0
94#endif
95
96#ifndef __has_extension
97#define __has_extension(x) 0
98#endif
99
100#ifndef HAVE_C___ASSUME
101#define HAVE_C___ASSUME MSC_PREREQ(8,0,0)
102#endif
103
104#ifndef HAVE_C___BUILTIN_UNREACHABLE
105#define HAVE_C___BUILTIN_UNREACHABLE (GNUC_PREREQ(4,5,0) || __has_builtin(__builtin_unreachable))
106#endif
107
108#ifndef HAVE_C___DECLSPEC_NORETURN
109#define HAVE_C___DECLSPEC_NORETURN MSC_PREREQ(8,0,0)
110#endif
111
112#ifndef HAVE_ASN1_STRING_GET0_DATA
113#define HAVE_ASN1_STRING_GET0_DATA OPENSSL_PREREQ(1,1,0)
114#endif
115
116#ifndef HAVE_DH_GET0_KEY
117#define HAVE_DH_GET0_KEY OPENSSL_PREREQ(1,1,0)
118#endif
119
120#ifndef HAVE_DH_GET0_PQG
121#define HAVE_DH_GET0_PQG OPENSSL_PREREQ(1,1,0)
122#endif
123
124#ifndef HAVE_DH_SET0_KEY
125#define HAVE_DH_SET0_KEY OPENSSL_PREREQ(1,1,0)
126#endif
127
128#ifndef HAVE_DH_SET0_PQG
129#define HAVE_DH_SET0_PQG OPENSSL_PREREQ(1,1,0)
130#endif
131
132#ifndef HAVE_DSA_GET0_KEY
133#define HAVE_DSA_GET0_KEY OPENSSL_PREREQ(1,1,0)
134#endif
135
136#ifndef HAVE_DSA_GET0_PQG
137#define HAVE_DSA_GET0_PQG OPENSSL_PREREQ(1,1,0)
138#endif
139
140#ifndef HAVE_DSA_SET0_KEY
141#define HAVE_DSA_SET0_KEY OPENSSL_PREREQ(1,1,0)
142#endif
143
144#ifndef HAVE_DSA_SET0_PQG
145#define HAVE_DSA_SET0_PQG OPENSSL_PREREQ(1,1,0)
146#endif
147
148#ifndef HAVE_DTLSV1_CLIENT_METHOD
149#define HAVE_DTLSV1_CLIENT_METHOD (!defined OPENSSL_NO_DTLS1)
150#endif
151
152#ifndef HAVE_DTLSV1_SERVER_METHOD
153#define HAVE_DTLSV1_SERVER_METHOD HAVE_DTLSV1_CLIENT_METHOD
154#endif
155
156#ifndef HAVE_DTLS_CLIENT_METHOD
157#define HAVE_DTLS_CLIENT_METHOD (OPENSSL_PREREQ(1,0,2) && !defined OPENSSL_NO_DTLS1)
158#endif
159
160#ifndef HAVE_DTLS_SERVER_METHOD
161#define HAVE_DTLS_SERVER_METHOD HAVE_DTLS_CLIENT_METHOD
162#endif
163
164#ifndef HAVE_DTLSV1_2_CLIENT_METHOD
165#define HAVE_DTLSV1_2_CLIENT_METHOD (OPENSSL_PREREQ(1,0,2) && !defined OPENSSL_NO_DTLS1)
166#endif
167
168#ifndef HAVE_DTLSV1_2_SERVER_METHOD
169#define HAVE_DTLSV1_2_SERVER_METHOD HAVE_DTLSV1_2_CLIENT_METHOD
170#endif
171
172#ifndef HAVE_EVP_CIPHER_CTX_FREE
173#define HAVE_EVP_CIPHER_CTX_FREE OPENSSL_PREREQ(1,1,0)
174#endif
175
176#ifndef HAVE_EVP_CIPHER_CTX_NEW
177#define HAVE_EVP_CIPHER_CTX_NEW OPENSSL_PREREQ(1,1,0)
178#endif
179
180#ifndef HAVE_EVP_MD_CTX_FREE
181#define HAVE_EVP_MD_CTX_FREE OPENSSL_PREREQ(1,1,0)
182#endif
183
184#ifndef HAVE_EVP_MD_CTX_NEW
185#define HAVE_EVP_MD_CTX_NEW OPENSSL_PREREQ(1,1,0)
186#endif
187
188#ifndef HAVE_EVP_PKEY_GET_DEFAULT_DIGEST_NID
189#define HAVE_EVP_PKEY_GET_DEFAULT_DIGEST_NID OPENSSL_PREREQ(0,9,9)
190#endif
191
192#ifndef HAVE_EVP_PKEY_BASE_ID
193#define HAVE_EVP_PKEY_BASE_ID OPENSSL_PREREQ(1,1,0)
194#endif
195
196#ifndef HAVE_EVP_PKEY_CTX_NEW
197#define HAVE_EVP_PKEY_CTX_NEW (OPENSSL_PREREQ(1,0,0) || LIBRESSL_PREREQ(2,0,0))
198#endif
199
200#ifndef HAVE_EVP_PKEY_GET0
201#define HAVE_EVP_PKEY_GET0 OPENSSL_PREREQ(1,1,0)
202#endif
203
204#ifndef HAVE_EVP_PKEY_ID
205#define HAVE_EVP_PKEY_ID OPENSSL_PREREQ(1,1,0)
206#endif
207
208#ifndef HAVE_HMAC_CTX_FREE
209#define HAVE_HMAC_CTX_FREE OPENSSL_PREREQ(1,1,0)
210#endif
211
212#ifndef HAVE_HMAC_CTX_NEW
213#define HAVE_HMAC_CTX_NEW OPENSSL_PREREQ(1,1,0)
214#endif
215
216#ifndef HAVE_I2D_RE_X509_REQ_TBS
217#define HAVE_I2D_RE_X509_REQ_TBS OPENSSL_PREREQ(1,1,0)
218#endif
219
220#ifndef HAVE_RSA_GET0_CRT_PARAMS
221#define HAVE_RSA_GET0_CRT_PARAMS OPENSSL_PREREQ(1,1,0)
222#endif
223
224#ifndef HAVE_RSA_GET0_FACTORS
225#define HAVE_RSA_GET0_FACTORS OPENSSL_PREREQ(1,1,0)
226#endif
227
228#ifndef HAVE_RSA_GET0_KEY
229#define HAVE_RSA_GET0_KEY OPENSSL_PREREQ(1,1,0)
230#endif
231
232#ifndef HAVE_RSA_PKCS1_PSS_PADDING
233#define HAVE_RSA_PKCS1_PSS_PADDING (defined RSA_PKCS1_PSS_PADDING || OPENSSL_PREREQ(1,0,0) || LIBRESSL_PREREQ(2,0,0))
234#endif
235
236#ifndef HAVE_RSA_SET0_CRT_PARAMS
237#define HAVE_RSA_SET0_CRT_PARAMS OPENSSL_PREREQ(1,1,0)
238#endif
239
240#ifndef HAVE_RSA_SET0_FACTORS
241#define HAVE_RSA_SET0_FACTORS OPENSSL_PREREQ(1,1,0)
242#endif
243
244#ifndef HAVE_RSA_SET0_KEY
245#define HAVE_RSA_SET0_KEY OPENSSL_PREREQ(1,1,0)
246#endif
247
248#ifndef HAVE_SSL_CLIENT_VERSION
249#define HAVE_SSL_CLIENT_VERSION OPENSSL_PREREQ(1,1,0)
250#endif
251
252#ifndef HAVE_SSL_CTX_GET0_PARAM
253#define HAVE_SSL_CTX_GET0_PARAM OPENSSL_PREREQ(1,0,2)
254#endif
255
256#ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS
257#define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,1,3))
258#endif
259
260#ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
261#define HAVE_SSL_CTX_SET_ALPN_SELECT_CB HAVE_SSL_CTX_SET_ALPN_PROTOS
262#endif
263
264#ifndef HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK
265#define HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK OPENSSL_PREREQ(1,0,0)
266#endif
267
268#ifndef HAVE_SSL_CTX_SET1_CERT_STORE
269#define HAVE_SSL_CTX_SET1_CERT_STORE (HAVE_SSL_CTX_set1_cert_store || 0) /* backwards compatible with old macro name */
270#endif
271
272#ifndef HAVE_SSL_CTX_SET1_PARAM
273#define HAVE_SSL_CTX_SET1_PARAM (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,1,0))
274#endif
275
276#ifndef HAVE_SSL_CTX_CERT_STORE
277#define HAVE_SSL_CTX_CERT_STORE (!OPENSSL_PREREQ(1,1,0))
278#endif
279
280#ifndef HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE
281#define HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE OPENSSL_PREREQ(1,1,0)
282#endif
283
284#ifndef HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE
285#define HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE OPENSSL_PREREQ(1,1,0)
286#endif
287
288#ifndef HAVE_SSL_GET0_ALPN_SELECTED
289#define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS
290#endif
291
292#ifndef HAVE_SSL_GET0_PARAM
293#define HAVE_SSL_GET0_PARAM OPENSSL_PREREQ(1,0,2)
294#endif
295
296#ifndef HAVE_SSL_SET_ALPN_PROTOS
297#define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS
298#endif
299
300#ifndef HAVE_SSL_SET1_PARAM
301#define HAVE_SSL_SET1_PARAM OPENSSL_PREREQ(1,0,2)
302#endif
303
304#ifndef HAVE_SSL_GET_CLIENT_RANDOM
305#define HAVE_SSL_GET_CLIENT_RANDOM OPENSSL_PREREQ(1,1,0)
306#endif
307
308#ifndef HAVE_SSL_GET_TLSEXT_STATUS_TYPE
309#define HAVE_SSL_GET_TLSEXT_STATUS_TYPE OPENSSL_PREREQ(1,1,0)
310#endif
311
312#ifndef HAVE_SSL_UP_REF
313#define HAVE_SSL_UP_REF OPENSSL_PREREQ(1,1,0)
314#endif
315
316#ifndef HAVE_SSLV2_CLIENT_METHOD
317#define HAVE_SSLV2_CLIENT_METHOD (!OPENSSL_PREREQ(1,1,0) && !defined OPENSSL_NO_SSL2)
318#endif
319
320#ifndef HAVE_SSLV2_SERVER_METHOD
321#define HAVE_SSLV2_SERVER_METHOD (!OPENSSL_PREREQ(1,1,0) && !defined OPENSSL_NO_SSL2)
322#endif
323
324#ifndef HAVE_X509_GET_SIGNATURE_NID
325#define HAVE_X509_GET_SIGNATURE_NID OPENSSL_PREREQ(1,0,2)
326#endif
327
328#ifndef HAVE_X509_STORE_REFERENCES
329#define HAVE_X509_STORE_REFERENCES (!OPENSSL_PREREQ(1,1,0))
330#endif
331
332#ifndef HAVE_X509_STORE_UP_REF
333#define HAVE_X509_STORE_UP_REF OPENSSL_PREREQ(1,1,0)
334#endif
335
336#ifndef HAVE_X509_UP_REF
337#define HAVE_X509_UP_REF OPENSSL_PREREQ(1,1,0)
338#endif
339
340#ifndef HAVE_X509_VERIFY_PARAM_ADD1_HOST
341#define HAVE_X509_VERIFY_PARAM_ADD1_HOST OPENSSL_PREREQ(1,0,2)
342#endif
343
344#ifndef HAVE_X509_VERIFY_PARAM_SET_AUTH_LEVEL
345#define HAVE_X509_VERIFY_PARAM_SET_AUTH_LEVEL OPENSSL_PREREQ(1,1,0)
346#endif
347
348#ifndef HAVE_X509_VERIFY_PARAM_SET1_EMAIL
349#define HAVE_X509_VERIFY_PARAM_SET1_EMAIL OPENSSL_PREREQ(1,0,2)
350#endif
351
352#ifndef HAVE_X509_VERIFY_PARAM_SET1_HOST
353#define HAVE_X509_VERIFY_PARAM_SET1_HOST OPENSSL_PREREQ(1,0,2)
354#endif
355
356#ifndef HAVE_X509_VERIFY_PARAM_SET1_IP_ASC
357#define HAVE_X509_VERIFY_PARAM_SET1_IP_ASC OPENSSL_PREREQ(1,0,2)
358#endif
359
360#ifndef HMAC_INIT_EX_INT
361#define HMAC_INIT_EX_INT OPENSSL_PREREQ(1,0,0)
362#endif
363
364#ifndef STRERROR_R_CHAR_P
365#define STRERROR_R_CHAR_P (defined __GLIBC__ && (_GNU_SOURCE || !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)))
366#endif
367
368#ifndef LIST_HEAD
369#define LIST_HEAD(name, type) struct name { struct type *lh_first; }
370#define LIST_ENTRY(type) struct { struct type *le_next, **le_prev; }
371#define LIST_INIT(head) do { LIST_FIRST((head)) = NULL; } while (0)
372#define LIST_FIRST(head) ((head)->lh_first)
373#define LIST_NEXT(elm, field) ((elm)->field.le_next)
374#define LIST_REMOVE(elm, field) do { \
375 if (LIST_NEXT((elm), field) != NULL) \
376 LIST_NEXT((elm), field)->field.le_prev = (elm)->field.le_prev; \
377 *(elm)->field.le_prev = LIST_NEXT((elm), field); \
378} while (0)
379#define LIST_INSERT_HEAD(head, elm, field) do { \
380 if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
381 LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \
382 LIST_FIRST((head)) = (elm); \
383 (elm)->field.le_prev = &LIST_FIRST((head)); \
384} while (0)
385#endif
386
387#define BIGNUM_CLASS "BIGNUM*"
388#define PKEY_CLASS "EVP_PKEY*"
389#define EC_GROUP_CLASS "EVP_GROUP*"
390#define X509_NAME_CLASS "X509_NAME*"
391#define X509_GENS_CLASS "GENERAL_NAMES*"
392#define X509_EXT_CLASS "X509_EXTENSION*"
393#define X509_CERT_CLASS "X509*"
394#define X509_CHAIN_CLASS "STACK_OF(X509)*"
395#define X509_CSR_CLASS "X509_REQ*"
396#define X509_CRL_CLASS "X509_CRL*"
397#define X509_STORE_CLASS "X509_STORE*"
398#define X509_VERIFY_PARAM_CLASS "X509_VERIFY_PARAM*"
399#define X509_STCTX_CLASS "X509_STORE_CTX*"
400#define PKCS12_CLASS "PKCS12*"
401#define SSL_CTX_CLASS "SSL_CTX*"
402#define SSL_CLASS "SSL*"
403#define DIGEST_CLASS "EVP_MD_CTX*"
404#define HMAC_CLASS "HMAC_CTX*"
405#define CIPHER_CLASS "EVP_CIPHER_CTX*"
406#define OCSP_RESPONSE_CLASS "OCSP_RESPONSE*"
407#define OCSP_BASICRESP_CLASS "OCSP_BASICRESP*"
408
409
410#if __GNUC__
411#define NOTUSED __attribute__((unused))
412#else
413#define NOTUSED
414#endif
415
416#if HAVE_C___BUILTIN_UNREACHABLE
417#define NOTREACHED __builtin_unreachable()
418#elif HAVE_C___ASSUME
419#define NOTREACHED __assume(0)
420#else
421#define NOTREACHED (void)0
422#endif
423
424#define countof(a) (sizeof (a) / sizeof *(a))
425#define endof(a) (&(a)[countof(a)])
426
427#define CLAMP(i, min, max) (((i) < (min))? (min) : ((i) > (max))? (max) : (i))
428
429#undef MIN
430#define MIN(a, b) (((a) < (b))? (a) : (b))
431
432#define stricmp(a, b) strcasecmp((a), (b))
433#define strieq(a, b) (!stricmp((a), (b)))
434
435#define xtolower(c) tolower((unsigned char)(c))
436
437#define SAY_(file, func, line, fmt, ...) \
438 fprintf(stderr, "%s:%d: " fmt "%s", __func__, __LINE__, __VA_ARGS__)
439
440#define SAY(...) SAY_(__FILE__, __func__, __LINE__, __VA_ARGS__, "\n")
441
442#define HAI SAY("hai")
443
444
445#define xitoa_putc(c) do { if (p < lim) dst[p] = (c); p++; } while (0)
446
447static const char *xitoa(char *dst, size_t lim, long i) {
448 size_t p = 0;
449 unsigned long d = 1000000000UL, n = 0, r;
450
451 if (i < 0) {
452 xitoa_putc('-');
453 i *= -1;
454 }
455
456 if ((i = MIN(2147483647L, i))) {
457 do {
458 if ((r = i / d) || n) {
459 i -= r * d;
460 n++;
461 xitoa_putc('0' + r);
462 }
463 } while (d /= 10);
464 } else {
465 xitoa_putc('0');
466 }
467
468 if (lim)
469 dst[MIN(p, lim - 1)] = '\0';
470
471 return dst;
472} /* xitoa() */
473
474
475static _Bool optbool(lua_State *L, int idx, _Bool d) {
476 if (lua_isnoneornil(L, idx))
477 return d;
478 luaL_checktype(L, idx, LUA_TBOOLEAN);
479 return lua_toboolean(L, idx);
480} /* optbool() */
481
482
483static void *prepudata(lua_State *L, size_t size, const char *tname, int (*gc)(lua_State *)) {
484 void *p = memset(lua_newuserdata(L, size), 0, size);
485
486 if (tname) {
487 luaL_setmetatable(L, tname);
488 } else {
489 lua_newtable(L);
490 lua_pushcfunction(L, gc);
491 lua_setfield(L, -2, "__gc");
492 lua_setmetatable(L, -2);
493 }
494
495 return p;
496} /* prepudata() */
497
498
499static void *prepsimple(lua_State *L, const char *tname, int (*gc)(lua_State *)) {
500 void **p = prepudata(L, sizeof (void *), tname, gc);
501 return p;
502} /* prepsimple() */
503
504#define prepsimple_(a, b, c, ...) prepsimple((a), (b), (c))
505#define prepsimple(...) prepsimple_(__VA_ARGS__, 0, 0)
506
507
508static void *checksimple(lua_State *L, int index, const char *tname) {
509 void **p;
510
511 if (tname) {
512 p = luaL_checkudata(L, index, tname);
513 } else {
514 luaL_checktype(L, index, LUA_TUSERDATA);
515 p = lua_touserdata(L, index);
516 }
517
518 return *p;
519} /* checksimple() */
520
521
522static void *testsimple(lua_State *L, int index, const char *tname) {
523 void **p;
524
525 if (tname) {
526 p = luaL_testudata(L, index, tname);
527 } else {
528 luaL_checktype(L, index, LUA_TUSERDATA);
529 p = lua_touserdata(L, index);
530 }
531
532 return (p)? *p : (void *)0;
533} /* testsimple() */
534
535
536static int auxL_swapmetatable(lua_State *, const char *);
537static int auxL_swapmetasubtable(lua_State *, const char *, const char *);
538
539static int interpose(lua_State *L, const char *mt) {
540 if (!strncmp("__", luaL_checkstring(L, lua_absindex(L, -2)), 2)) {
541 return auxL_swapmetatable(L, mt);
542 } else {
543 return auxL_swapmetasubtable(L, mt, "__index");
544 }
545} /* interpose() */
546
547static int auxL_checkoption(lua_State *, int, const char *, const char *const *, _Bool);
548
549#define X509_ANY 0x01
550#define X509_PEM 0x02
551#define X509_DER 0x04
552#define X509_TXT 0x08 /* "pretty" */
553#define X509_ALL (X509_PEM|X509_DER)
554
555static int optencoding(lua_State *L, int index, const char *def, int allow) {
556 static const char *const opts[] = { "*", "pem", "der", "pretty", NULL };
557 int type = 0;
558
559 switch (auxL_checkoption(L, index, def, opts, 1)) {
560 case 0:
561 type = X509_ANY;
562 break;
563 case 1:
564 type = X509_PEM;
565 break;
566 case 2:
567 type = X509_DER;
568 break;
569 case 3:
570 type = X509_TXT;
571 break;
572 }
573
574 if (!(type & allow))
575 luaL_argerror(L, index, lua_pushfstring(L, "invalid option %s", luaL_checkstring(L, index)));
576
577 return type;
578} /* optencoding() */
579
580
581static _Bool rawgeti(lua_State *L, int index, int n) {
582 lua_rawgeti(L, index, n);
583
584 if (lua_isnil(L, -1)) {
585 lua_pop(L, 1);
586
587 return 0;
588 } else {
589 return 1;
590 }
591} /* rawgeti() */
592
593
594/* check ALPN protocols and add to buffer of length-prefixed strings */
595static void checkprotos(luaL_Buffer *B, lua_State *L, int index) {
596 int n;
597
598 luaL_checktype(L, index, LUA_TTABLE);
599
600 for (n = 1; rawgeti(L, index, n); n++) {
601 const char *tmp;
602 size_t len;
603
604 switch (lua_type(L, -1)) {
605 case LUA_TSTRING:
606 break;
607 default:
608 luaL_argerror(L, index, "array of strings expected");
609 }
610
611 tmp = luaL_checklstring(L, -1, &len);
612 luaL_argcheck(L, len > 0 && len <= UCHAR_MAX, index, "proto string length invalid");
613 luaL_addchar(B, (unsigned char)len);
614 luaL_addlstring(B, tmp, len);
615 lua_pop(L, 1);
616 }
617} /* checkprotos() */
618
619static void pushprotos(lua_State *L, const unsigned char *p, size_t n) {
620 const unsigned char *pe = &p[n];
621 int i = 0;
622
623 lua_newtable(L);
624
625 while (p < pe) {
626 n = *p++;
627
628 if ((size_t)(pe - p) < n)
629 luaL_error(L, "corrupt ALPN protocol list (%zu > %zu)", n, (size_t)(pe - p));
630
631 lua_pushlstring(L, (const void *)p, n);
632 lua_rawseti(L, -2, ++i);
633 p += n;
634 }
635} /* pushprotos() */
636
637
638static _Bool getfield(lua_State *L, int index, const char *k) {
639 lua_getfield(L, index, k);
640
641 if (lua_isnil(L, -1)) {
642 lua_pop(L, 1);
643
644 return 0;
645 } else {
646 return 1;
647 }
648} /* getfield() */
649
650
651static _Bool loadfield(lua_State *L, int index, const char *k, int type, void *p) {
652 if (!getfield(L, index, k))
653 return 0;
654
655 switch (type) {
656 case LUA_TSTRING:
657 *(const char **)p = luaL_checkstring(L, -1);
658 break;
659 case LUA_TNUMBER:
660 *(lua_Number *)p = luaL_checknumber(L, -1);
661 break;
662 default:
663 luaL_error(L, "loadfield(type=%d): invalid type", type);
664 break;
665 } /* switch() */
666
667 lua_pop(L, 1); /* table keeps reference */
668
669 return 1;
670} /* loadfield() */
671
672
673static void *loadfield_udata(lua_State *L, int index, const char *k, const char *tname) {
674 if (!getfield(L, index, k))
675 return NULL;
676
677 void **p = luaL_checkudata(L, -1, tname);
678
679 lua_pop(L, 1); /* table keeps reference */
680
681 return *p;
682} /* loadfield_udata() */
683
684
685/* Forward declaration */
686static SSL *ssl_push(lua_State *, SSL *);
687
688/* push an ssl object into lua in a way that is safe from OOM
689 * Lua 5.1 does not support normally returning values from lua_cpcall
690 * to return a value, we instead return it via an error object
691 */
692static int ssl_pushsafe_helper(lua_State *L) {
693 ssl_push(L, lua_touserdata(L, 1));
694#if LUA_VERSION_NUM <= 501
695 return lua_error(L);
696#else
697 return 1;
698#endif
699}
700
701static int ssl_pushsafe(lua_State *L, SSL *ssl) {
702 int status;
703#if LUA_VERSION_NUM <= 501
704 status = lua_cpcall(L, ssl_pushsafe_helper, ssl);
705 if (status == LUA_ERRRUN)
706 status = LUA_OK;
707 else if (status == LUA_OK)
708 /* this should be impossible */
709 status = LUA_ERRRUN;
710 else
711 lua_pop(L, 1);
712#else
713 lua_pushcfunction(L, ssl_pushsafe_helper);
714 lua_pushlightuserdata(L, ssl);
715 status = lua_pcall(L, 1, 1, 0);
716 if (status != LUA_OK)
717 lua_pop(L, 1);
718#endif
719 return status;
720}
721
722
723/*
724 * Auxiliary C routines
725 *
726 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
727
728#define AUX_MIN(a, b) (((a) < (b))? (a) : (b))
729
730static size_t aux_strlcpy(char *dst, const char *src, size_t lim) {
731 size_t n = strlen(src);
732
733 if (lim > 0) {
734 size_t m = AUX_MIN(lim - 1, n);
735
736 memcpy(dst, src, m);
737 dst[m] = '\0';
738 }
739
740 return n;
741} /* aux_strlcpy() */
742
743#define aux_strerror(error) aux_strerror_r((error), (char[256]){ 0 }, 256)
744
745static const char *aux_strerror_r(int error, char *dst, size_t lim) {
746 static const char unknown[] = "Unknown error: ";
747 size_t n;
748
749#if STRERROR_R_CHAR_P
750 char *rv = strerror_r(error, dst, lim);
751
752 if (rv != NULL)
753 return dst;
754#else
755 int rv = strerror_r(error, dst, lim);
756
757 if (0 == rv)
758 return dst;
759#endif
760
761 /*
762 * glibc snprintf can fail on memory pressure, so format our number
763 * manually.
764 */
765 n = MIN(sizeof unknown - 1, lim);
766 memcpy(dst, unknown, n);
767
768 return xitoa(&dst[n], lim - n, error);
769} /* aux_strerror_r() */
770
771
772/*
773 * Auxiliary OpenSSL API routines
774 *
775 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
776
777static void auxS_bn_free_and_set0(BIGNUM **dst, BIGNUM *src) {
778 if (*dst) {
779 BN_clear_free(*dst);
780 }
781 *dst = src;
782} /* auxS_bn_free_and_set0() */
783
784static size_t auxS_nid2sn(void *dst, size_t lim, int nid) {
785 const char *sn;
786
787 if (nid == NID_undef || !(sn = OBJ_nid2sn(nid)))
788 return 0;
789
790 return aux_strlcpy(dst, sn, lim);
791} /* aux2_nid2sn() */
792
793static size_t auxS_obj2sn(void *dst, size_t lim, const ASN1_OBJECT *obj) {
794 return auxS_nid2sn(dst, lim, OBJ_obj2nid(obj));
795} /* auxS_obj2sn() */
796
797static size_t auxS_nid2ln(void *dst, size_t lim, int nid) {
798 const char *ln;
799
800 if (nid == NID_undef || !(ln = OBJ_nid2ln(nid)))
801 return 0;
802
803 return aux_strlcpy(dst, ln, lim);
804} /* aux2_nid2ln() */
805
806static size_t auxS_obj2ln(void *dst, size_t lim, const ASN1_OBJECT *obj) {
807 return auxS_nid2ln(dst, lim, OBJ_obj2nid(obj));
808} /* auxS_obj2ln() */
809
810static size_t auxS_obj2id(void *dst, size_t lim, const ASN1_OBJECT *obj) {
811 int n = OBJ_obj2txt(dst, AUX_MIN(lim, INT_MAX), obj, 1);
812
813 /* TODO: push custom errors onto error stack */
814 if (n == 0) {
815 return 0; /* obj->data == NULL */
816 } else if (n < 0) {
817 return 0; /* memory allocation error */
818 } else {
819 return n;
820 }
821} /* auxS_obj2id() */
822
823static size_t auxS_nid2id(void *dst, size_t lim, int nid) {
824 ASN1_OBJECT *obj;
825
826 /* TODO: push custom error onto error stack */
827 if (!(obj = OBJ_nid2obj(nid)))
828 return 0;
829
830 return auxS_obj2id(dst, lim, obj);
831} /* auxS_nid2id() */
832
833static size_t auxS_nid2txt(void *dst, size_t lim, int nid) {
834 size_t n;
835
836 if ((n = auxS_nid2sn(dst, lim, nid)))
837 return n;
838 if ((n = auxS_nid2ln(dst, lim, nid)))
839 return n;
840
841 return auxS_nid2id(dst, lim, nid);
842} /* auxS_nid2txt() */
843
844static size_t auxS_obj2txt(void *dst, size_t lim, const ASN1_OBJECT *obj) {
845 size_t n;
846
847 if ((n = auxS_obj2sn(dst, lim, obj)))
848 return n;
849 if ((n = auxS_obj2ln(dst, lim, obj)))
850 return n;
851
852 return auxS_obj2id(dst, lim, obj);
853} /* auxS_obj2txt() */
854
855static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def);
856
857static _Bool auxS_isoid(const char *txt) {
858 return (*txt >= '0' && *txt <= '9');
859} /* auxS_isoid() */
860
861static _Bool auxS_txt2obj(ASN1_OBJECT **obj, const char *txt) {
862 int nid;
863
864 if ((nid = OBJ_sn2nid(txt)) != NID_undef
865 || (nid = OBJ_ln2nid(txt)) != NID_undef) {
866 return NULL != (*obj = OBJ_nid2obj(nid));
867 } else if (auxS_isoid(txt)) {
868 return NULL != (*obj = OBJ_txt2obj(txt, 1));
869 } else {
870 *obj = NULL;
871 return 1;
872 }
873} /* auxS_txt2obj() */
874
875static _Bool auxS_txt2nid(int *nid, const char *txt) {
876 /* try builtins first */
877 if ((*nid = OBJ_sn2nid(txt)) != NID_undef
878 || (*nid = OBJ_ln2nid(txt)) != NID_undef) {
879 return 1;
880 }
881
882 /* OBJ_txt2nid creates a temporary ASN1_OBJECT; call sparingly */
883 if (auxS_isoid(txt) && (*nid = OBJ_txt2nid(txt)) != NID_undef) {
884 return 1;
885 }
886
887 return 0;
888} /* auxS_txt2nid() */
889
890
891/*
892 * Auxiliary Lua API routines
893 *
894 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
895
896typedef int auxref_t;
897typedef int auxtype_t;
898
899static void auxL_unref(lua_State *L, auxref_t *ref) {
900 luaL_unref(L, LUA_REGISTRYINDEX, *ref);
901 *ref = LUA_NOREF;
902} /* auxL_unref() */
903
904static void auxL_ref(lua_State *L, int index, auxref_t *ref) {
905 auxL_unref(L, ref);
906 lua_pushvalue(L, index);
907 *ref = luaL_ref(L, LUA_REGISTRYINDEX);
908} /* auxL_ref() */
909
910NOTUSED static auxtype_t auxL_getref(lua_State *L, auxref_t ref) {
911 if (ref == LUA_NOREF || ref == LUA_REFNIL) {
912 lua_pushnil(L);
913 } else {
914 lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
915 }
916
917 return lua_type(L, -1);
918} /* auxL_getref() */
919
920static int auxL_testoption(lua_State *L, int index, const char *def, const char *const *optlist, _Bool nocase) {
921 const char *optname = (def)? luaL_optstring(L, index, def) : luaL_checkstring(L, index);
922 int (*optcmp)() = (nocase)? &strcasecmp : &strcmp;
923 int i;
924
925 for (i = 0; optlist[i]; i++) {
926 if (0 == optcmp(optlist[i], optname))
927 return i;
928 }
929
930 return -1;
931} /* auxL_testoption() */
932
933static int auxL_checkoption(lua_State *L, int index, const char *def, const char *const *optlist, _Bool nocase) {
934 int i;
935
936 if ((i = auxL_testoption(L, index, def, optlist, nocase)) >= 0)
937 return i;
938
939 return luaL_argerror(L, index, lua_pushfstring(L, "invalid option '%s'", luaL_optstring(L, index, def)));
940} /* auxL_checkoption() */
941
942/*
943 * Lua 5.3 distinguishes integers and numbers, and by default uses 64-bit
944 * integers. The following routines try to preserve this distinction and
945 * where possible detect range issues.
946 *
947 * The signed range checking assumes two's complement, no padding bits, and
948 * sizeof lua_Integer <= sizeof long long. Which is a safe bet where OpenSSL
949 * is typically used.
950 */
951#define auxL_Integer long long
952#define auxL_IntegerMin LLONG_MIN
953#define auxL_IntegerMax LLONG_MAX
954#define auxL_Unsigned unsigned long long
955#define auxL_UnsignedMin 0
956#define auxL_UnsignedMax ULLONG_MAX
957
958#define lua_IntegerMax ((1ULL << (sizeof (lua_Integer) * 8 - 1)) - 1)
959#define lua_IntegerMin (-lua_IntegerMax - 1)
960
961static void auxL_pushinteger(lua_State *L, auxL_Integer i) {
962 /*
963 * TODO: Check value explicitly, but will need to silence compiler
964 * diagnostics about useless comparisons.
965 */
966 if (sizeof (lua_Integer) >= sizeof i) {
967 lua_pushinteger(L, i);
968 } else {
969 /* TODO: Check overflow. */
970 lua_pushnumber(L, i);
971 }
972} /* auxL_pushinteger() */
973
974static void auxL_pushunsigned(lua_State *L, auxL_Unsigned i) {
975 if (i <= lua_IntegerMax) {
976 lua_pushinteger(L, i);
977 } else if (i == (auxL_Unsigned)(lua_Number)i) {
978 lua_pushnumber(L, i);
979 } else {
980 luaL_error(L, "unsigned integer value not representable as lua_Integer or lua_Number");
981 }
982} /* auxL_pushunsigned() */
983
984#define auxL_checkinteger_(a, b, c, d, ...) auxL_checkinteger((a), (b), (c), (d))
985#define auxL_checkinteger(...) auxL_checkinteger_(__VA_ARGS__, auxL_IntegerMin, auxL_IntegerMax, 0)
986
987static auxL_Integer (auxL_checkinteger)(lua_State *L, int index, auxL_Integer min, auxL_Integer max) {
988 auxL_Integer i;
989
990 if (sizeof (lua_Integer) >= sizeof (auxL_Integer)) {
991 i = luaL_checkinteger(L, index);
992 } else {
993 /* TODO: Check overflow. */
994 i = (auxL_Integer)luaL_checknumber(L, index);
995 }
996
997 if (i < min || i > max)
998 luaL_error(L, "integer value out of range");
999
1000 return i;
1001} /* auxL_checkinteger() */
1002
1003#define auxL_optinteger_(a, b, c, d, e, ...) auxL_optinteger((a), (b), (c), (d), (e))
1004#define auxL_optinteger(...) auxL_optinteger_(__VA_ARGS__, auxL_IntegerMin, auxL_IntegerMax, 0)
1005
1006static auxL_Integer (auxL_optinteger)(lua_State *L, int index, auxL_Integer def, auxL_Integer min, auxL_Integer max) {
1007 return (lua_isnoneornil(L, index))? def : auxL_checkinteger(L, index, min, max);
1008} /* auxL_optinteger() */
1009
1010#define auxL_checkunsigned_(a, b, c, d, ...) auxL_checkunsigned((a), (b), (c), (d))
1011#define auxL_checkunsigned(...) auxL_checkunsigned_(__VA_ARGS__, auxL_UnsignedMin, auxL_UnsignedMax, 0)
1012
1013static auxL_Unsigned (auxL_checkunsigned)(lua_State *L, int index, auxL_Unsigned min, auxL_Unsigned max) {
1014 auxL_Unsigned i;
1015
1016 if (sizeof (lua_Integer) >= sizeof (auxL_Unsigned)) {
1017 /* TODO: Check sign. */
1018 i = luaL_checkinteger(L, index);
1019 } else {
1020 /* TODO: Check sign and overflow. */
1021 i = (auxL_Integer)luaL_checknumber(L, index);
1022 }
1023
1024 if (i < min || i > max)
1025 luaL_error(L, "integer value out of range");
1026
1027 return i;
1028} /* auxL_checkunsigned() */
1029
1030#define auxL_optunsigned_(a, b, c, d, e, ...) auxL_optunsigned((a), (b), (c), (d), (e))
1031#define auxL_optunsigned(...) auxL_optunsigned_(__VA_ARGS__, auxL_UnsignedMin, auxL_UnsignedMax, 0)
1032
1033static auxL_Unsigned (auxL_optunsigned)(lua_State *L, int index, auxL_Unsigned def, auxL_Unsigned min, auxL_Unsigned max) {
1034 return (lua_isnoneornil(L, index))? def : auxL_checkunsigned(L, index, min, max);
1035} /* auxL_optunsigned() */
1036
1037static int auxL_size2int(lua_State *L, size_t n) {
1038 if (n > INT_MAX)
1039 luaL_error(L, "integer value out of range (%zu > INT_MAX)", n);
1040
1041 return (int)n;
1042} /* auxL_size2int() */
1043
1044typedef struct {
1045 const char *name;
1046 auxL_Integer value;
1047} auxL_IntegerReg;
1048
1049static void auxL_setintegers(lua_State *L, const auxL_IntegerReg *l) {
1050 for (; l->name; l++) {
1051 auxL_pushinteger(L, l->value);
1052 lua_setfield(L, -2, l->name);
1053 }
1054} /* auxL_setintegers() */
1055
1056#define AUXL_REG_NULL (&(auxL_Reg[]){ 0 })
1057
1058typedef struct {
1059 const char *name;
1060 lua_CFunction func;
1061 unsigned nups; /* in addition to nups specified to auxL_setfuncs */
1062} auxL_Reg;
1063
1064static inline size_t auxL_liblen(const auxL_Reg *l) {
1065 size_t n = 0;
1066
1067 while ((l++)->name)
1068 n++;
1069
1070 return n;
1071} /* auxL_liblen() */
1072
1073#define auxL_newlibtable(L, l) \
1074 lua_createtable((L), 0, countof((l)) - 1)
1075
1076#define auxL_newlib(L, l, nups) \
1077 (auxL_newlibtable((L), (l)), lua_insert((L), -(nups + 1)), auxL_setfuncs((L), (l), (nups)))
1078
1079static void auxL_setfuncs(lua_State *L, const auxL_Reg *l, int nups) {
1080 for (; l->name; l++) {
1081 int i;
1082
1083 /* copy shared upvalues */
1084 luaL_checkstack(L, nups, "too many upvalues");
1085 for (i = 0; i < nups; i++)
1086 lua_pushvalue(L, -nups);
1087
1088 /* nil-fill local upvalues */
1089 luaL_checkstack(L, l->nups, "too many upvalues");
1090 lua_settop(L, lua_gettop(L) + l->nups);
1091
1092 /* set closure */
1093 luaL_checkstack(L, 1, "too many upvalues");
1094 lua_pushcclosure(L, l->func, nups + l->nups);
1095 lua_setfield(L, -(nups + 2), l->name);
1096 }
1097
1098 lua_pop(L, nups);
1099
1100 return;
1101} /* auxL_setfuncs() */
1102
1103static void auxL_clear(lua_State *L, int tindex) {
1104 tindex = lua_absindex(L, tindex);
1105
1106 lua_pushnil(L);
1107 while (lua_next(L, tindex)) {
1108 lua_pop(L, 1);
1109 lua_pushvalue(L, -1);
1110 lua_pushnil(L);
1111 lua_rawset(L, tindex);
1112 }
1113} /* auxL_clear() */
1114
1115static _Bool auxL_newmetatable(lua_State *L, const char *name, _Bool reset) {
1116 if (luaL_newmetatable(L, name))
1117 return 1;
1118 if (!reset)
1119 return 0;
1120
1121 /*
1122 * NB: Keep existing table as it may be cached--e.g. in
1123 * another module that isn't being reloaded. But scrub it
1124 * clean so function interposition--which will presumably
1125 * run again if the C module is being reloaded--doesn't
1126 * result in loops.
1127 */
1128 auxL_clear(L, -1);
1129 lua_pushnil(L);
1130 lua_setmetatable(L, -2);
1131#if LUA_VERSION_NUM >= 502
1132 lua_pushnil(L);
1133 lua_setuservalue(L, -2);
1134#endif
1135
1136 return 0;
1137} /* auxL_newmetatable() */
1138
1139static _Bool auxL_newclass(lua_State *L, const char *name, const auxL_Reg *methods, const auxL_Reg *metamethods, _Bool reset) {
1140 _Bool fresh = auxL_newmetatable(L, name, reset);
1141 int n;
1142
1143 auxL_setfuncs(L, metamethods, 0);
1144
1145 if ((n = auxL_liblen(methods))) {
1146 lua_createtable(L, 0, auxL_size2int(L, n));
1147 auxL_setfuncs(L, methods, 0);
1148 lua_setfield(L, -2, "__index");
1149 }
1150
1151 return fresh;
1152} /* auxL_newclass() */
1153
1154#define auxL_addclass(L, ...) \
1155 (auxL_newclass((L), __VA_ARGS__), lua_pop((L), 1))
1156
1157static int auxL_swaptable(lua_State *L, int index) {
1158 index = lua_absindex(L, index);
1159
1160 lua_pushvalue(L, -2); /* push key */
1161 lua_gettable(L, index); /* push old value */
1162
1163 lua_pushvalue(L, -3); /* push key */
1164 lua_pushvalue(L, -3); /* push new value */
1165 lua_settable(L, index); /* replace old value */
1166
1167 lua_replace(L, -3);
1168 lua_pop(L, 1);
1169
1170 return 1; /* return old value */
1171} /* auxL_swaptable() */
1172
1173static int auxL_swapmetatable(lua_State *L, const char *name) {
1174 luaL_getmetatable(L, name);
1175
1176 lua_pushvalue(L, -3);
1177 lua_pushvalue(L, -3);
1178 auxL_swaptable(L, -3);
1179
1180 lua_replace(L, -4);
1181 lua_pop(L, 2);
1182
1183 return 1;
1184} /* auxL_swapmetatable() */
1185
1186static int auxL_swapmetasubtable(lua_State *L, const char *name, const char *subname) {
1187 luaL_getmetatable(L, name);
1188 lua_getfield(L, -1, subname);
1189
1190 lua_pushvalue(L, -4);
1191 lua_pushvalue(L, -4);
1192 auxL_swaptable(L, -3);
1193
1194 lua_replace(L, -5);
1195 lua_pop(L, 3);
1196
1197 return 1;
1198} /* auxL_swapmetasubtable() */
1199
1200#define auxL_EDYLD -2
1201#define auxL_EOPENSSL -1
1202
1203static const char *auxL_pusherror(lua_State *L, int error, const char *fun) {
1204 if (error == auxL_EOPENSSL) {
1205 unsigned long code;
1206 const char *path, *file;
1207 int line;
1208 char txt[256];
1209
1210 if (!ERR_peek_error())
1211 return lua_pushstring(L, "oops: no OpenSSL errors set");
1212
1213 code = ERR_get_error_line(&path, &line);
1214
1215 if ((file = strrchr(path, '/'))) {
1216 ++file;
1217 } else {
1218 file = path;
1219 }
1220
1221 ERR_clear_error();
1222
1223 ERR_error_string_n(code, txt, sizeof txt);
1224
1225 if (fun) {
1226 return lua_pushfstring(L, "%s: %s:%d:%s", fun, file, line, txt);
1227 } else {
1228 return lua_pushfstring(L, "%s:%d:%s", file, line, txt);
1229 }
1230 } else if (error == auxL_EDYLD) {
1231 const char *const fmt = (fun)? "%s: %s" : "%.0s%s";
1232
1233 return lua_pushfstring(L, fmt, (fun)? fun : "", dlerror());
1234 } else {
1235 const char *const fmt = (fun)? "%s: %s" : "%.0s%s";
1236
1237 return lua_pushfstring(L, fmt, (fun)? fun : "", aux_strerror(error));
1238 }
1239} /* auxL_pusherror() */
1240
1241static int auxL_error(lua_State *L, int error, const char *fun) {
1242 auxL_pusherror(L, error, fun);
1243 lua_error(L);
1244 NOTREACHED;
1245 return 0;
1246} /* auxL_error() */
1247
1248static const char *auxL_pushnid(lua_State *L, int nid) {
1249 char txt[256] = { 0 };
1250 size_t n;
1251
1252 if (!(n = auxS_nid2txt(txt, sizeof txt, nid)) || n >= sizeof txt)
1253 luaL_error(L, "%d: invalid ASN.1 NID", nid);
1254
1255 lua_pushlstring(L, txt, n);
1256
1257 return lua_tostring(L, -1);
1258} /* auxL_pushnid() */
1259
1260static const EVP_MD *auxL_optdigest(lua_State *L, int index, EVP_PKEY *key, const EVP_MD *def);
1261
1262
1263/*
1264 * dl - dynamically loaded module management
1265 *
1266 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1267
1268/*
1269 * Prevent loader from unlinking us if we've registered a callback with
1270 * OpenSSL by taking another reference to ourselves.
1271 */
1272static int dl_anchor(void) {
1273#if HAVE_DLADDR
1274 extern int luaopen__openssl(lua_State *);
1275 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1276 static void *anchor;
1277 Dl_info info;
1278 int error = 0;
1279
1280 if ((error = pthread_mutex_lock(&mutex)))
1281 return error;
1282
1283 if (anchor)
1284 goto epilog;
1285
1286 if (!dladdr((void *)&luaopen__openssl, &info))
1287 goto dlerr;
1288
1289 if (!(anchor = dlopen(info.dli_fname, RTLD_NOW|RTLD_LOCAL)))
1290 goto dlerr;
1291epilog:
1292 (void)pthread_mutex_unlock(&mutex);
1293
1294 return error;
1295dlerr:
1296 error = auxL_EDYLD;
1297
1298 goto epilog;
1299#else
1300 return 0;//ENOTSUP;
1301#endif
1302} /* dl_anchor() */
1303
1304
1305/*
1306 * compat - OpenSSL API compatibility and bug workarounds
1307 *
1308 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1309
1310#define COMPAT_X509_STORE_FREE_BUG 0x01
1311
1312static struct {
1313 int flags;
1314
1315 void (*X509_STORE_free)(X509_STORE *);
1316
1317 struct {
1318 X509_STORE *store;
1319 } tmp;
1320} compat = {
1321 .flags = 0,
1322 .X509_STORE_free = &X509_STORE_free,
1323};
1324
1325#if !HAVE_ASN1_STRING_GET0_DATA
1326#define ASN1_STRING_get0_data(s) ASN1_STRING_data((s))
1327#endif
1328
1329#if !HAVE_DH_GET0_KEY
1330#define DH_get0_key(...) compat_DH_get0_key(__VA_ARGS__)
1331
1332static void compat_DH_get0_key(const DH *d, const BIGNUM **pub_key, const BIGNUM **priv_key) {
1333 if (pub_key)
1334 *pub_key = d->pub_key;
1335 if (priv_key)
1336 *priv_key = d->priv_key;
1337} /* compat_DH_get0_key() */
1338#endif
1339
1340#if !HAVE_DH_GET0_PQG
1341#define DH_get0_pqg(...) compat_DH_get0_pqg(__VA_ARGS__)
1342
1343static void compat_DH_get0_pqg(const DH *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) {
1344 if (p)
1345 *p = d->p;
1346 if (q)
1347 *q = d->q;
1348 if (g)
1349 *g = d->g;
1350} /* compat_DH_get0_pqg() */
1351#endif
1352
1353#if !HAVE_DH_SET0_KEY
1354#define DH_set0_key(...) compat_DH_set0_key(__VA_ARGS__)
1355
1356static void compat_DH_set0_key(DH *d, BIGNUM *pub_key, BIGNUM *priv_key) {
1357 if (pub_key)
1358 auxS_bn_free_and_set0(&d->pub_key, pub_key);
1359 if (priv_key)
1360 auxS_bn_free_and_set0(&d->priv_key, priv_key);
1361} /* compat_DH_set0_key() */
1362#endif
1363
1364#if !HAVE_DH_SET0_PQG
1365#define DH_set0_pqg(...) compat_DH_set0_pqg(__VA_ARGS__)
1366
1367static void compat_DH_set0_pqg(DH *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
1368 if (p)
1369 auxS_bn_free_and_set0(&d->p, p);
1370 if (q)
1371 auxS_bn_free_and_set0(&d->q, q);
1372 if (g)
1373 auxS_bn_free_and_set0(&d->g, g);
1374} /* compat_DH_set0_pqg() */
1375#endif
1376
1377#if !HAVE_DSA_GET0_KEY
1378#define DSA_get0_key(...) compat_DSA_get0_key(__VA_ARGS__)
1379
1380static void compat_DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) {
1381 if (pub_key)
1382 *pub_key = d->pub_key;
1383 if (priv_key)
1384 *priv_key = d->priv_key;
1385} /* compat_DSA_get0_key() */
1386#endif
1387
1388#if !HAVE_DSA_GET0_PQG
1389#define DSA_get0_pqg(...) compat_DSA_get0_pqg(__VA_ARGS__)
1390
1391static void compat_DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) {
1392 if (p)
1393 *p = d->p;
1394 if (q)
1395 *q = d->q;
1396 if (g)
1397 *g = d->g;
1398} /* compat_DSA_get0_pqg() */
1399#endif
1400
1401#if !HAVE_DSA_SET0_KEY
1402#define DSA_set0_key(...) compat_DSA_set0_key(__VA_ARGS__)
1403
1404static void compat_DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) {
1405 if (pub_key)
1406 auxS_bn_free_and_set0(&d->pub_key, pub_key);
1407 if (priv_key)
1408 auxS_bn_free_and_set0(&d->priv_key, priv_key);
1409} /* compat_DSA_set0_key() */
1410#endif
1411
1412#if !HAVE_DSA_SET0_PQG
1413#define DSA_set0_pqg(...) compat_DSA_set0_pqg(__VA_ARGS__)
1414
1415static void compat_DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
1416 if (p)
1417 auxS_bn_free_and_set0(&d->p, p);
1418 if (q)
1419 auxS_bn_free_and_set0(&d->q, q);
1420 if (g)
1421 auxS_bn_free_and_set0(&d->g, g);
1422} /* compat_DSA_set0_pqg() */
1423#endif
1424
1425#if !HAVE_EVP_CIPHER_CTX_FREE
1426#define EVP_CIPHER_CTX_free(ctx) compat_EVP_CIPHER_CTX_free((ctx))
1427
1428static void compat_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) {
1429 EVP_CIPHER_CTX_cleanup(ctx);
1430 OPENSSL_free(ctx);
1431} /* compat_EVP_CIPHER_CTX_free() */
1432#endif
1433
1434#if !HAVE_EVP_CIPHER_CTX_NEW
1435#define EVP_CIPHER_CTX_new() compat_EVP_CIPHER_CTX_new()
1436
1437static EVP_CIPHER_CTX *compat_EVP_CIPHER_CTX_new(void) {
1438 EVP_CIPHER_CTX *ctx;
1439
1440 if (!(ctx = OPENSSL_malloc(sizeof *ctx)))
1441 return NULL;
1442 memset(ctx, 0, sizeof *ctx);
1443 EVP_CIPHER_CTX_init(ctx);
1444
1445 return ctx;
1446} /* compat_EVP_CIPHER_CTX_new() */
1447#endif
1448
1449#if !HAVE_EVP_MD_CTX_FREE
1450#define EVP_MD_CTX_free(md) EVP_MD_CTX_destroy((md))
1451#endif
1452
1453#if !HAVE_EVP_MD_CTX_NEW
1454#define EVP_MD_CTX_new(md) EVP_MD_CTX_create()
1455#endif
1456
1457#if !HAVE_EVP_PKEY_ID
1458#define EVP_PKEY_id(key) ((key)->type)
1459#endif
1460
1461#if !HAVE_EVP_PKEY_BASE_ID
1462#define EVP_PKEY_base_id(key) compat_EVP_PKEY_base_id((key))
1463
1464static int compat_EVP_PKEY_base_id(EVP_PKEY *key) {
1465 return EVP_PKEY_type(EVP_PKEY_id(key));
1466} /* compat_EVP_PKEY_base_id() */
1467#endif
1468
1469#if !HAVE_EVP_PKEY_GET_DEFAULT_DIGEST_NID
1470#define EVP_PKEY_get_default_digest_nid(...) \
1471 compat_EVP_PKEY_get_default_digest_nid(__VA_ARGS__)
1472
1473static int compat_EVP_PKEY_get_default_digest_nid(EVP_PKEY *key, int *nid) {
1474 switch (EVP_PKEY_base_id(key)) {
1475 case EVP_PKEY_RSA:
1476 *nid = EVP_MD_nid(EVP_sha1());
1477 break;
1478 case EVP_PKEY_DSA:
1479 *nid = EVP_MD_nid(EVP_dss1());
1480 break;
1481 case EVP_PKEY_EC:
1482 *nid = EVP_MD_nid(EVP_ecdsa());
1483 break;
1484 default:
1485 *nid = EVP_MD_nid(EVP_sha1());
1486 break;
1487 }
1488
1489 return 1;
1490} /* compat_EVP_PKEY_get_default_digest_nid() */
1491#endif
1492
1493#if !HAVE_EVP_PKEY_GET0
1494#define EVP_PKEY_get0(key) compat_EVP_PKEY_get0((key))
1495
1496static void *compat_EVP_PKEY_get0(EVP_PKEY *key) {
1497 void *ptr = NULL;
1498
1499 switch (EVP_PKEY_base_id(key)) {
1500 case EVP_PKEY_RSA:
1501 if ((ptr = EVP_PKEY_get1_RSA(key)))
1502 RSA_free(ptr);
1503 break;
1504 case EVP_PKEY_DSA:
1505 if ((ptr = EVP_PKEY_get1_DSA(key)))
1506 DSA_free(ptr);
1507 break;
1508 case EVP_PKEY_DH:
1509 if ((ptr = EVP_PKEY_get1_DH(key)))
1510 DH_free(ptr);
1511 break;
1512#ifndef OPENSSL_NO_EC
1513 case EVP_PKEY_EC:
1514 if ((ptr = EVP_PKEY_get1_EC_KEY(key)))
1515 EC_KEY_free(ptr);
1516 break;
1517#endif
1518 default:
1519 /* TODO: Use ERR_put_error */
1520
1521 break;
1522 }
1523
1524 return ptr;
1525} /* compat_EVP_PKEY_get0() */
1526#endif
1527
1528#if !HAVE_HMAC_CTX_FREE
1529#define HMAC_CTX_free(ctx) compat_HMAC_CTX_free((ctx))
1530
1531static void compat_HMAC_CTX_free(HMAC_CTX *ctx) {
1532 HMAC_CTX_cleanup(ctx);
1533 OPENSSL_free(ctx);
1534} /* compat_HMAC_CTX_free() */
1535#endif
1536
1537#if !HAVE_HMAC_CTX_NEW
1538#define HMAC_CTX_new() compat_HMAC_CTX_new()
1539
1540static HMAC_CTX *compat_HMAC_CTX_new(void) {
1541 HMAC_CTX *ctx;
1542
1543 if (!(ctx = OPENSSL_malloc(sizeof *ctx)))
1544 return NULL;
1545 memset(ctx, 0, sizeof *ctx);
1546
1547 return ctx;
1548} /* compat_HMAC_CTX_new() */
1549#endif
1550
1551#if !HAVE_RSA_GET0_CRT_PARAMS
1552#define RSA_get0_crt_params(...) compat_RSA_get0_crt_params(__VA_ARGS__)
1553
1554static void compat_RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp) {
1555 if (dmp1)
1556 *dmp1 = r->dmp1;
1557 if (dmq1)
1558 *dmq1 = r->dmq1;
1559 if (iqmp)
1560 *iqmp = r->iqmp;
1561} /* compat_RSA_get0_crt_params() */
1562#endif
1563
1564#if !HAVE_RSA_GET0_FACTORS
1565#define RSA_get0_factors(...) compat_RSA_get0_factors(__VA_ARGS__)
1566
1567static void compat_RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) {
1568 if (p)
1569 *p = r->p;
1570 if (q)
1571 *q = r->q;
1572} /* compat_RSA_get0_factors() */
1573#endif
1574
1575#if !HAVE_RSA_GET0_KEY
1576#define RSA_get0_key(...) compat_RSA_get0_key(__VA_ARGS__)
1577
1578static void compat_RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) {
1579 if (n)
1580 *n = r->n;
1581 if (e)
1582 *e = r->e;
1583 if (d)
1584 *d = r->d;
1585} /* compat_RSA_get0_key() */
1586#endif
1587
1588#if !HAVE_RSA_SET0_CRT_PARAMS
1589#define RSA_set0_crt_params(...) compat_RSA_set0_crt_params(__VA_ARGS__)
1590
1591static void compat_RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) {
1592 if (dmp1)
1593 auxS_bn_free_and_set0(&r->dmp1, dmp1);
1594 if (dmq1)
1595 auxS_bn_free_and_set0(&r->dmq1, dmq1);
1596 if (iqmp)
1597 auxS_bn_free_and_set0(&r->iqmp, iqmp);
1598} /* compat_RSA_set0_crt_params() */
1599#endif
1600
1601#if !HAVE_RSA_SET0_FACTORS
1602#define RSA_set0_factors(...) compat_RSA_set0_factors(__VA_ARGS__)
1603
1604static void compat_RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) {
1605 if (p)
1606 auxS_bn_free_and_set0(&r->p, p);
1607 if (q)
1608 auxS_bn_free_and_set0(&r->q, q);
1609} /* compat_RSA_set0_factors() */
1610#endif
1611
1612#if !HAVE_RSA_SET0_KEY
1613#define RSA_set0_key(...) compat_RSA_set0_key(__VA_ARGS__)
1614
1615static void compat_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
1616 if (n)
1617 auxS_bn_free_and_set0(&r->n, n);
1618 if (e)
1619 auxS_bn_free_and_set0(&r->e, e);
1620 if (d)
1621 auxS_bn_free_and_set0(&r->d, d);
1622} /* compat_RSA_set0_key() */
1623#endif
1624
1625#if !HAVE_SSL_GET_CLIENT_RANDOM
1626#define SSL_get_client_random(...) compat_SSL_get_client_random(__VA_ARGS__)
1627static size_t compat_SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen) {
1628 if (outlen == 0)
1629 return sizeof(ssl->s3->client_random);
1630 if (outlen > sizeof(ssl->s3->client_random))
1631 outlen = sizeof(ssl->s3->client_random);
1632 memcpy(out, ssl->s3->client_random, outlen);
1633 return outlen;
1634}
1635#endif
1636
1637#if !HAVE_SSL_CLIENT_VERSION
1638#define SSL_client_version(...) compat_SSL_client_version(__VA_ARGS__)
1639
1640static int compat_SSL_client_version(const SSL *ssl) {
1641 return ssl->client_version;
1642} /* compat_SSL_client_version() */
1643#endif
1644
1645#if !HAVE_SSL_GET0_PARAM
1646#define SSL_get0_param(ssl) compat_SSL_get0_param((ssl))
1647
1648static X509_VERIFY_PARAM *compat_SSL_get0_param(SSL *ssl) {
1649 return ssl->param;
1650} /* compat_SSL_get0_param() */
1651#endif
1652
1653#if !HAVE_SSL_SET1_PARAM
1654#define SSL_set1_param(ssl, vpm) compat_SSL_set1_param((ssl), (vpm))
1655
1656static int compat_SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) {
1657 return X509_VERIFY_PARAM_set1(ssl->param, vpm);
1658} /* compat_SSL_set1_param() */
1659#endif
1660
1661#if !HAVE_SSL_UP_REF
1662#define SSL_up_ref(...) compat_SSL_up_ref(__VA_ARGS__)
1663
1664static int compat_SSL_up_ref(SSL *ssl) {
1665 /* our caller should already have had a proper reference */
1666 if (CRYPTO_add(&ssl->references, 1, CRYPTO_LOCK_SSL) < 2)
1667 return 0; /* fail */
1668
1669 return 1;
1670} /* compat_SSL_up_ref() */
1671#endif
1672
1673#if !HAVE_SSL_CTX_GET0_PARAM
1674#define SSL_CTX_get0_param(ctx) compat_SSL_CTX_get0_param((ctx))
1675
1676static X509_VERIFY_PARAM *compat_SSL_CTX_get0_param(SSL_CTX *ctx) {
1677 return ctx->param;
1678} /* compat_SSL_CTX_get0_param() */
1679#endif
1680
1681#if !HAVE_SSL_CTX_SET1_PARAM
1682#define SSL_CTX_set1_param(ctx, vpm) compat_SSL_CTX_set1_param((ctx), (vpm))
1683
1684static int compat_SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) {
1685 return X509_VERIFY_PARAM_set1(ctx->param, vpm);
1686} /* compat_SSL_CTX_set1_param() */
1687#endif
1688
1689#if !HAVE_X509_GET0_EXT
1690#define X509_get0_ext(crt, i) X509_get_ext((crt), (i))
1691#endif
1692
1693#if !HAVE_X509_GET_SIGNATURE_NID
1694#define X509_get_signature_nid(crt) OBJ_obj2nid((crt)->sig_alg->algorithm)
1695#endif
1696
1697#if !HAVE_X509_CRL_GET0_EXT
1698#define X509_CRL_get0_ext(crt, i) X509_CRL_get_ext((crt), (i))
1699#endif
1700
1701#if !HAVE_X509_EXTENSION_GET0_OBJECT
1702#define X509_EXTENSION_get0_object(ext) X509_EXTENSION_get_object((ext))
1703#endif
1704
1705#if !HAVE_X509_EXTENSION_GET0_DATA
1706#define X509_EXTENSION_get0_data(ext) X509_EXTENSION_get_data((ext))
1707#endif
1708
1709#if HAVE_X509_STORE_REFERENCES
1710/*
1711 * X509_STORE_free in OpenSSL versions < 1.0.2 doesn't obey reference count
1712 */
1713#define X509_STORE_free(store) \
1714 (compat.X509_STORE_free)((store))
1715
1716/* to support preprocessor detection below */
1717#define compat_X509_STORE_free(store) \
1718 compat_X509_STORE_free((store))
1719
1720static void (compat_X509_STORE_free)(X509_STORE *store) {
1721 int i;
1722
1723 i = CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE);
1724
1725 if (i > 0)
1726 return;
1727
1728 (X509_STORE_free)(store);
1729} /* compat_X509_STORE_free() */
1730#endif
1731
1732#if !HAVE_SSL_CTX_SET1_CERT_STORE
1733#if !HAVE_SSL_CTX_CERT_STORE || !HAVE_X509_STORE_REFERENCES
1734#define SSL_CTX_set1_cert_store(ctx, store) \
1735 SSL_CTX_set_cert_store((ctx), (store))
1736#else
1737#define SSL_CTX_set1_cert_store(ctx, store) \
1738 compat_SSL_CTX_set1_cert_store((ctx), (store))
1739
1740/* to support preprocessor detection below */
1741#define compat_SSL_CTX_set1_cert_store(ctx, store) \
1742 compat_SSL_CTX_set1_cert_store((ctx), (store))
1743
1744static void (compat_SSL_CTX_set1_cert_store)(SSL_CTX *ctx, X509_STORE *store) {
1745 int n;
1746
1747 /*
1748 * This isn't thead-safe, but using X509_STORE or SSL_CTX objects
1749 * from different threads isn't safe generally.
1750 */
1751 if (ctx->cert_store) {
1752 X509_STORE_free(ctx->cert_store);
1753 ctx->cert_store = NULL;
1754 }
1755
1756 n = store->references;
1757
1758 SSL_CTX_set_cert_store(ctx, store);
1759
1760 if (n == store->references)
1761 CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
1762} /* compat_SSL_CTX_set1_cert_store() */
1763#endif
1764#endif
1765
1766#if HAVE_SSL_CTX_CERT_STORE
1767
1768static void compat_init_SSL_CTX_onfree(void *_ctx, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
1769 SSL_CTX *ctx = _ctx;
1770
1771 if (ctx->cert_store) {
1772 X509_STORE_free(ctx->cert_store);
1773 ctx->cert_store = NULL;
1774 }
1775} /* compat_init_SSL_CTX_onfree() */
1776
1777#endif
1778
1779/* helper routine to determine if X509_STORE_free obeys reference count */
1780static void compat_init_X509_STORE_onfree(void *store, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
1781 /* unfortunately there's no way to remove a handler */
1782 if (store != compat.tmp.store)
1783 return;
1784
1785 /* signal that we were freed by nulling our reference */
1786 compat.tmp.store = NULL;
1787} /* compat_init_X509_STORE_onfree() */
1788
1789#if !HAVE_X509_STORE_UP_REF
1790#define X509_STORE_up_ref(...) compat_X509_STORE_up_ref(__VA_ARGS__)
1791
1792static int compat_X509_STORE_up_ref(X509_STORE *crt) {
1793 /* our caller should already have had a proper reference */
1794 if (CRYPTO_add(&crt->references, 1, CRYPTO_LOCK_X509_STORE) < 2)
1795 return 0; /* fail */
1796
1797 return 1;
1798} /* compat_X509_STORE_up_ref() */
1799#endif
1800
1801#if !HAVE_X509_UP_REF
1802#define X509_up_ref(...) compat_X509_up_ref(__VA_ARGS__)
1803
1804static int compat_X509_up_ref(X509 *crt) {
1805 /* our caller should already have had a proper reference */
1806 if (CRYPTO_add(&crt->references, 1, CRYPTO_LOCK_X509) < 2)
1807 return 0; /* fail */
1808
1809 return 1;
1810} /* compat_X509_up_ref() */
1811#endif
1812
1813#if !HAVE_X509_VERIFY_PARAM_SET1_EMAIL
1814/*
1815 * NB: Cannot emulate. Requires dereferencing X509_VERIFY_PARAM_ID objects,
1816 * which were always opaque.
1817 */
1818#endif
1819
1820#if !HAVE_X509_VERIFY_PARAM_SET1_HOST
1821/*
1822 * NB: See HAVE_X509_VERIFY_PARAM_SET1_EMAIL.
1823 */
1824#endif
1825
1826static int compat_init(void) {
1827 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1828 static int store_index = -1, ssl_ctx_index = -1, done;
1829 int error = 0;
1830
1831 if ((error = pthread_mutex_lock(&mutex)))
1832 return error;
1833
1834 if (done)
1835 goto epilog;
1836
1837 /*
1838 * We need to unconditionally install at least one external
1839 * application data callback. Because these can never be
1840 * uninstalled, we can never be unloaded.
1841 */
1842 if ((error = dl_anchor()))
1843 goto epilog;
1844
1845#if defined compat_X509_STORE_free
1846 /*
1847 * Test if X509_STORE_free obeys reference counts by installing an
1848 * onfree callback.
1849 */
1850 if (store_index == -1
1851 && -1 == (store_index = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, 0, NULL, NULL, NULL, &compat_init_X509_STORE_onfree)))
1852 goto sslerr;
1853
1854 if (!(compat.tmp.store = X509_STORE_new()))
1855 goto sslerr;
1856
1857 CRYPTO_add(&compat.tmp.store->references, 1, CRYPTO_LOCK_X509_STORE);
1858 X509_STORE_free(compat.tmp.store);
1859
1860 if (compat.tmp.store) {
1861 /*
1862 * Because our onfree callback didn't execute, we assume
1863 * X509_STORE_free obeys reference counts. Alternatively,
1864 * our callback might not have executed for some other
1865 * reason. We assert the truth of our assumption by checking
1866 * again after calling X509_STORE_free once more.
1867 */
1868 X509_STORE_free(compat.tmp.store);
1869 assert(compat.tmp.store == NULL);
1870 compat.tmp.store = NULL; /* in case assertions disabled */
1871 } else {
1872 /*
1873 * Because our onfree callback was invoked, X509_STORE_free
1874 * appears not to obey reference counts. Use our fixed
1875 * version in our own code.
1876 */
1877 compat.X509_STORE_free = &compat_X509_STORE_free;
1878
1879 /*
1880 * Ensure that our fixed version is called on SSL_CTX
1881 * destruction.
1882 *
1883 * NB: We depend on the coincidental order of operations in
1884 * SSL_CTX_free that user data destruction occurs before
1885 * free'ing the cert_store member. Ruby's OpenSSL bindings
1886 * also depend on this order as we both use the onfree
1887 * callback to clear the member.
1888 */
1889 if (ssl_ctx_index == -1
1890 && -1 == (ssl_ctx_index = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, 0, NULL, NULL, NULL, &compat_init_SSL_CTX_onfree)))
1891 goto sslerr;
1892
1893 compat.flags |= COMPAT_X509_STORE_FREE_BUG;
1894 }
1895#endif
1896
1897 done = 1;
1898epilog:
1899 if (compat.tmp.store) {
1900 X509_STORE_free(compat.tmp.store);
1901 compat.tmp.store = NULL;
1902 }
1903
1904 (void)pthread_mutex_unlock(&mutex);
1905
1906 return error;
1907sslerr:
1908 error = auxL_EOPENSSL;
1909
1910 goto epilog;
1911} /* compat_init() */
1912
1913
1914/*
1915 * Auxiliary OpenSSL API routines (with dependencies on OpenSSL compat)
1916 *
1917 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1918
1919static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def) {
1920 const EVP_MD *md;
1921 int nid;
1922
1923 if (name) {
1924 if ((md = EVP_get_digestbyname(name)))
1925 return md;
1926 } else if (key) {
1927 if ((EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) {
1928 if ((md = EVP_get_digestbynid(nid)))
1929 return md;
1930 }
1931 }
1932
1933 return def;
1934} /* auxS_todigest() */
1935
1936
1937/*
1938 * Auxiliary Lua API routines (with dependencies on OpenSSL compat)
1939 *
1940 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1941
1942static const EVP_MD *auxL_optdigest(lua_State *L, int index, EVP_PKEY *key, const EVP_MD *def) {
1943 const char *name = luaL_optstring(L, index, NULL);
1944 const EVP_MD *md;
1945
1946 if ((md = auxS_todigest(name, key, NULL)))
1947 return md;
1948
1949 if (name) {
1950 luaL_argerror(L, index, lua_pushfstring(L, "invalid digest type (%s)", name));
1951 NOTREACHED;
1952 } else if (key) {
1953 luaL_argerror(L, index, lua_pushfstring(L, "no digest type for key type (%d)", EVP_PKEY_base_id(key)));
1954 NOTREACHED;
1955 }
1956
1957 return def;
1958} /* auxL_optdigest() */
1959
1960
1961/*
1962 * External Application Data Hooks
1963 *
1964 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1965
1966struct ex_state {
1967 lua_State *L;
1968 LIST_HEAD(, ex_data) data;
1969}; /* struct ex_state */
1970
1971#ifndef EX_DATA_MAXARGS
1972#define EX_DATA_MAXARGS 8
1973#endif
1974
1975struct ex_data {
1976 struct ex_state *state;
1977 int refs;
1978 auxref_t arg[EX_DATA_MAXARGS];
1979 LIST_ENTRY(ex_data) le;
1980}; /* struct ex_data */
1981
1982enum {
1983 EX_SSL_CTX_ALPN_SELECT_CB,
1984 EX_SSL_CTX_TLSEXT_SERVERNAME_CB,
1985};
1986
1987static struct ex_type {
1988 int class_index; /* OpenSSL object type identifier */
1989 int index; /* OpenSSL-allocated external data identifier */
1990 void *(*get_ex_data)();
1991 int (*set_ex_data)();
1992} ex_type[] = {
1993 [EX_SSL_CTX_ALPN_SELECT_CB] = { CRYPTO_EX_INDEX_SSL_CTX, -1, &SSL_CTX_get_ex_data, &SSL_CTX_set_ex_data },
1994 [EX_SSL_CTX_TLSEXT_SERVERNAME_CB] = { CRYPTO_EX_INDEX_SSL_CTX, -1, &SSL_CTX_get_ex_data, &SSL_CTX_set_ex_data },
1995};
1996
1997#if OPENSSL_PREREQ(1,1,0)
1998typedef const CRYPTO_EX_DATA const_CRYPTO_EX_DATA;
1999#else
2000typedef CRYPTO_EX_DATA const_CRYPTO_EX_DATA;
2001#endif
2002
2003static int ex_ondup(CRYPTO_EX_DATA *to NOTUSED, const_CRYPTO_EX_DATA *from NOTUSED, void *from_d, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
2004 struct ex_data **data = from_d;
2005
2006 if (*data)
2007 (*data)->refs++;
2008
2009 return 1;
2010} /* ex_ondup() */
2011
2012static void ex_onfree(void *parent NOTUSED, void *_data, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
2013 struct ex_data *data = _data;
2014
2015 if (!data || --data->refs > 0)
2016 return;
2017
2018 if (data->state) {
2019 int i;
2020
2021 for (i = 0; i < (int)countof(data->arg); i++) {
2022 auxL_unref(data->state->L, &data->arg[i]);
2023 }
2024
2025 LIST_REMOVE(data, le);
2026 }
2027
2028 free(data);
2029} /* ex_onfree() */
2030
2031static int ex_init(void) {
2032 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
2033 static int done;
2034 struct ex_type *type;
2035 int error = 0;
2036
2037 if ((error = pthread_mutex_lock(&mutex)))
2038 return error;
2039
2040 if (done)
2041 goto epilog;
2042
2043 /*
2044 * Our callbacks can never be uninstalled, so ensure we're never
2045 * unloaded.
2046 */
2047 if ((error = dl_anchor()))
2048 goto epilog;
2049
2050 for (type = ex_type; type < endof(ex_type); type++) {
2051 if (type->index != -1)
2052 continue;
2053
2054 if (-1 == (type->index = CRYPTO_get_ex_new_index(type->class_index, 0, NULL, NULL, &ex_ondup, &ex_onfree)))
2055 goto sslerr;
2056 };
2057
2058 done = 1;
2059epilog:
2060 (void)pthread_mutex_unlock(&mutex);
2061
2062 return error;
2063sslerr:
2064 error = auxL_EOPENSSL;
2065
2066 goto epilog;
2067} /* ex_init() */
2068
2069static int ex__gc(lua_State *L) {
2070 struct ex_state *state = lua_touserdata(L, 1);
2071 struct ex_data *data;
2072
2073 if (!state)
2074 return 0;
2075
2076 /* invalidate back references to Lua state */
2077 for (data = LIST_FIRST(&state->data); data; data = LIST_NEXT(data, le)) {
2078 data->state = NULL;
2079 }
2080
2081 return 0;
2082} /* ex__gc() */
2083
2084static _Bool ex_hasstate(lua_State *L) {
2085 _Bool has;
2086
2087 lua_pushlightuserdata(L, (void *)&ex__gc);
2088 lua_gettable(L, LUA_REGISTRYINDEX);
2089 has = !lua_isnil(L, -1);
2090 lua_pop(L, 1);
2091
2092 return has;
2093} /* ex_hasstate() */
2094
2095static void ex_newstate(lua_State *L) {
2096 struct ex_state *state;
2097 struct lua_State *thr;
2098
2099 if (ex_hasstate(L))
2100 return;
2101
2102 state = prepudata(L, sizeof *state, NULL, &ex__gc);
2103 LIST_INIT(&state->data);
2104
2105 /*
2106 * XXX: Don't reuse mainthread because if an error occurs in a
2107 * callback Lua might longjmp across the OpenSSL call stack.
2108 * Instead, we'll install our own panic handlers.
2109 */
2110#if defined LUA_RIDX_MAINTHREAD
2111 (void)thr;
2112 lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
2113 state->L = lua_tothread(L, -1);
2114 lua_pop(L, 1);
2115#else
2116 lua_pushvalue(L, -1);
2117 thr = lua_newthread(L);
2118 lua_settable(L, LUA_REGISTRYINDEX);
2119 state->L = thr;
2120#endif
2121
2122 lua_pushlightuserdata(L, (void *)&ex__gc);
2123 lua_pushvalue(L, -2);
2124 lua_settable(L, LUA_REGISTRYINDEX);
2125
2126 lua_pop(L, 1);
2127} /* ex_newstate() */
2128
2129static struct ex_state *ex_getstate(lua_State *L) {
2130 struct ex_state *state;
2131
2132 lua_pushlightuserdata(L, (void *)&ex__gc);
2133 lua_gettable(L, LUA_REGISTRYINDEX);
2134
2135 luaL_checktype(L, -1, LUA_TUSERDATA);
2136 state = lua_touserdata(L, -1);
2137 lua_pop(L, 1);
2138
2139 return state;
2140} /* ex_getstate() */
2141
2142static size_t ex_getdata(lua_State **L, int _type, void *obj) {
2143 struct ex_type *type = &ex_type[_type];
2144 struct ex_data *data;
2145 size_t i;
2146
2147 if (!(data = type->get_ex_data(obj, type->index)))
2148 return 0;
2149 if (!data->state)
2150 return 0;
2151
2152 if (!*L)
2153 *L = data->state->L;
2154
2155 if (!lua_checkstack(*L, countof(data->arg)))
2156 return 0;
2157
2158 for (i = 0; i < countof(data->arg) && data->arg[i] != LUA_NOREF; i++) {
2159 lua_rawgeti(*L, LUA_REGISTRYINDEX, data->arg[i]);
2160 }
2161
2162 return i;
2163} /* ex_getdata() */
2164
2165/* returns 0 on success, otherwise error (>0 == errno, -1 == OpenSSL error) */
2166static int ex_setdata(lua_State *L, int _type, void *obj, size_t n) {
2167 struct ex_type *type = &ex_type[_type];
2168 struct ex_state *state;
2169 struct ex_data *data;
2170 size_t i, j;
2171
2172 if (n > countof(data->arg))
2173 return EOVERFLOW;
2174
2175 if ((data = type->get_ex_data(obj, type->index)) && data->state) {
2176 for (i = 0; i < countof(data->arg); i++) {
2177 auxL_unref(L, &data->arg[i]);
2178 }
2179 } else {
2180 state = ex_getstate(L);
2181
2182 if (!(data = malloc(sizeof *data)))
2183 return errno;
2184
2185 if (!type->set_ex_data(obj, type->index, data))
2186 return auxL_EOPENSSL;
2187
2188 data->state = state;
2189 data->refs = 1;
2190 for (i = 0; i < countof(data->arg); i++)
2191 data->arg[i] = LUA_NOREF;
2192 LIST_INSERT_HEAD(&state->data, data, le);
2193 }
2194
2195 for (i = n, j = 0; i > 0 && j < countof(data->arg); i--, j++) {
2196 auxL_ref(L, -(int)i, &data->arg[j]);
2197 }
2198
2199 lua_pop(L, n);
2200
2201 return 0;
2202} /* ex_setdata() */
2203
2204static void initall(lua_State *L);
2205
2206
2207/*
2208 * compat - Lua OpenSSL
2209 *
2210 * Bindings to our internal feature detection, compatability, and workaround
2211 * code.
2212 *
2213 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2214
2215int luaopen__openssl_compat(lua_State *L) {
2216 initall(L);
2217
2218 lua_newtable(L);
2219 lua_pushboolean(L, !!(compat.flags & COMPAT_X509_STORE_FREE_BUG));
2220 lua_setfield(L, -2, "X509_STORE_FREE_BUG");
2221
2222 return 1;
2223} /* luaopen__openssl_compat() */
2224
2225
2226/*
2227 * OPENSSL - openssl
2228 *
2229 * Miscellaneous global interfaces.
2230 *
2231 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2232
2233static int ossl_version(lua_State *L) {
2234 if (lua_isnoneornil(L, 1)) {
2235 auxL_pushunsigned(L, SSLeay());
2236 } else {
2237 lua_pushstring(L, SSLeay_version(auxL_checkinteger(L, 1, INT_MIN, INT_MAX)));
2238 }
2239
2240 return 1;
2241} /* ossl_version() */
2242
2243static const auxL_Reg ossl_globals[] = {
2244 { "version", &ossl_version },
2245 { NULL, NULL },
2246};
2247
2248/*
2249 * NOTE: Compile-time cipher exclusions from openssl-1.0.1i/util/mkdef.pl.
2250 */
2251static const char opensslconf_no[][20] = {
2252#ifdef OPENSSL_NO_RC2
2253 { "NO_RC2" },
2254#endif
2255#ifdef OPENSSL_NO_RC4
2256 { "NO_RC4" },
2257#endif
2258#ifdef OPENSSL_NO_RC5
2259 { "NO_RC5" },
2260#endif
2261#ifdef OPENSSL_NO_IDEA
2262 { "NO_IDEA" },
2263#endif
2264#ifdef OPENSSL_NO_DES
2265 { "NO_DES" },
2266#endif
2267#ifdef OPENSSL_NO_BF
2268 { "NO_BF" },
2269#endif
2270#ifdef OPENSSL_NO_CAST
2271 { "NO_CAST" },
2272#endif
2273#ifdef OPENSSL_NO_WHIRLPOOL
2274 { "NO_WHIRLPOOL" },
2275#endif
2276#ifdef OPENSSL_NO_CAMELLIA
2277 { "NO_CAMELLIA" },
2278#endif
2279#ifdef OPENSSL_NO_SEED
2280 { "NO_SEED" },
2281#endif
2282#ifdef OPENSSL_NO_MD2
2283 { "NO_MD2" },
2284#endif
2285#ifdef OPENSSL_NO_MD4
2286 { "NO_MD4" },
2287#endif
2288#ifdef OPENSSL_NO_MD5
2289 { "NO_MD5" },
2290#endif
2291#ifdef OPENSSL_NO_SHA
2292 { "NO_SHA" },
2293#endif
2294#ifdef OPENSSL_NO_RIPEMD
2295 { "NO_RIPEMD" },
2296#endif
2297#ifdef OPENSSL_NO_MDC2
2298 { "NO_MDC2" },
2299#endif
2300#ifdef OPENSSL_NO_RSA
2301 { "NO_RSA" },
2302#endif
2303#ifdef OPENSSL_NO_DSA
2304 { "NO_DSA" },
2305#endif
2306#ifdef OPENSSL_NO_DH
2307 { "NO_DH" },
2308#endif
2309#ifdef OPENSSL_NO_HMAC
2310 { "NO_HMAC" },
2311#endif
2312#ifdef OPENSSL_NO_AES
2313 { "NO_AES" },
2314#endif
2315#ifdef OPENSSL_NO_KRB5
2316 { "NO_KRB5" },
2317#endif
2318#ifdef OPENSSL_NO_EC
2319 { "NO_EC" },
2320#endif
2321#ifdef OPENSSL_NO_ECDSA
2322 { "NO_ECDSA" },
2323#endif
2324#ifdef OPENSSL_NO_ECDH
2325 { "NO_ECDH" },
2326#endif
2327#ifdef OPENSSL_NO_ENGINE
2328 { "NO_ENGINE" },
2329#endif
2330#ifdef OPENSSL_NO_HW
2331 { "NO_HW" },
2332#endif
2333#ifdef OPENSSL_NO_FP_API
2334 { "NO_FP_API" },
2335#endif
2336#ifdef OPENSSL_NO_STATIC_ENGINE
2337 { "NO_STATIC_ENGINE" },
2338#endif
2339#ifdef OPENSSL_NO_GMP
2340 { "NO_GMP" },
2341#endif
2342#ifdef OPENSSL_NO_DEPRECATED
2343 { "NO_DEPRECATED" },
2344#endif
2345#ifdef OPENSSL_NO_RFC3779
2346 { "NO_RFC3779" },
2347#endif
2348#ifdef OPENSSL_NO_PSK
2349 { "NO_PSK" },
2350#endif
2351#ifdef OPENSSL_NO_TLSEXT
2352 { "NO_TLSEXT" },
2353#endif
2354#ifdef OPENSSL_NO_CMS
2355 { "NO_CMS" },
2356#endif
2357#ifdef OPENSSL_NO_CAPIENG
2358 { "NO_CAPIENG" },
2359#endif
2360#ifdef OPENSSL_NO_JPAKE
2361 { "NO_JPAKE" },
2362#endif
2363#ifdef OPENSSL_NO_SRP
2364 { "NO_SRP" },
2365#endif
2366#ifdef OPENSSL_NO_SSL2
2367 { "NO_SSL2" },
2368#endif
2369#ifdef OPENSSL_NO_EC2M
2370 { "NO_EC2M" },
2371#endif
2372#ifdef OPENSSL_NO_NISTP_GCC
2373 { "NO_NISTP_GCC" },
2374#endif
2375#ifdef OPENSSL_NO_NEXTPROTONEG
2376 { "NO_NEXTPROTONEG" },
2377#endif
2378#ifdef OPENSSL_NO_SCTP
2379 { "NO_SCTP" },
2380#endif
2381#ifdef OPENSSL_NO_UNIT_TEST
2382 { "NO_UNIT_TEST" },
2383#endif
2384 { "" } /* in case nothing is defined above */
2385}; /* opensslconf_no[] */
2386
2387static const auxL_IntegerReg ssleay_version[] = {
2388#ifdef SSLEAY_VERSION_NUMBER
2389 { "SSLEAY_VERSION_NUMBER", SSLEAY_VERSION_NUMBER },
2390#endif
2391#ifdef SSLEAY_VERSION
2392 { "SSLEAY_VERSION", SSLEAY_VERSION },
2393#endif
2394#ifdef SSLEAY_OPTIONS
2395 { "SSLEAY_OPTIONS", SSLEAY_OPTIONS },
2396#endif
2397#ifdef SSLEAY_CFLAGS
2398 { "SSLEAY_CFLAGS", SSLEAY_CFLAGS },
2399#endif
2400#ifdef SSLEAY_BUILT_ON
2401 { "SSLEAY_BUILT_ON", SSLEAY_BUILT_ON },
2402#endif
2403#ifdef SSLEAY_PLATFORM
2404 { "SSLEAY_PLATFORM", SSLEAY_PLATFORM },
2405#endif
2406#ifdef SSLEAY_DIR
2407 { "SSLEAY_DIR", SSLEAY_DIR },
2408#endif
2409 { NULL, 0 },
2410};
2411
2412int luaopen__openssl(lua_State *L) {
2413 size_t i;
2414
2415 auxL_newlib(L, ossl_globals, 0);
2416
2417 for (i = 0; i < countof(opensslconf_no); i++) {
2418 if (*opensslconf_no[i]) {
2419 lua_pushboolean(L, 1);
2420 lua_setfield(L, -2, opensslconf_no[i]);
2421 }
2422 }
2423
2424 auxL_setintegers(L, ssleay_version);
2425
2426 auxL_pushinteger(L, OPENSSL_VERSION_NUMBER);
2427 lua_setfield(L, -2, "VERSION_NUMBER");
2428
2429 lua_pushstring(L, OPENSSL_VERSION_TEXT);
2430 lua_setfield(L, -2, "VERSION_TEXT");
2431
2432 lua_pushstring(L, SHLIB_VERSION_HISTORY);
2433 lua_setfield(L, -2, "SHLIB_VERSION_HISTORY");
2434
2435 lua_pushstring(L, SHLIB_VERSION_NUMBER);
2436 lua_setfield(L, -2, "SHLIB_VERSION_NUMBER");
2437
2438#if defined LIBRESSL_VERSION_NUMBER
2439 auxL_pushinteger(L, LIBRESSL_VERSION_NUMBER);
2440 lua_setfield(L, -2, "LIBRESSL_VERSION_NUMBER");
2441#endif
2442
2443 return 1;
2444} /* luaopen__openssl() */
2445
2446
2447/*
2448 * BIGNUM - openssl.bignum
2449 *
2450 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2451
2452static BIGNUM *bn_push(lua_State *L) {
2453 BIGNUM **ud = prepsimple(L, BIGNUM_CLASS);
2454
2455 if (!(*ud = BN_new()))
2456 auxL_error(L, auxL_EOPENSSL, "bignum.new");
2457
2458 return *ud;
2459} /* bn_push() */
2460
2461
2462static BIGNUM *bn_dup(lua_State *L, const BIGNUM *src) {
2463 BIGNUM **ud = prepsimple(L, BIGNUM_CLASS);
2464
2465 if (!(*ud = BN_dup(src)))
2466 auxL_error(L, auxL_EOPENSSL, "bignum");
2467
2468 return *ud;
2469} /* bn_dup() */
2470
2471
2472static BIGNUM *bn_dup_nil(lua_State *L, const BIGNUM *src) {
2473 return (src)? bn_dup(L, src) : (lua_pushnil(L), (BIGNUM *)0);
2474} /* bn_dup_nil() */
2475
2476
2477#define checkbig_(a, b, c, ...) checkbig((a), (b), (c))
2478#define checkbig(...) checkbig_(__VA_ARGS__, &(_Bool){ 0 }, 0)
2479
2480static BIGNUM *(checkbig)(lua_State *, int, _Bool *);
2481
2482static int bn_new(lua_State *L) {
2483 int i, n;
2484
2485 if ((n = lua_gettop(L)) > 0) {
2486 for (i = 1; i <= n; i++)
2487 checkbig(L, i);
2488
2489 return n;
2490 } else {
2491 bn_push(L);
2492
2493 return 1;
2494 }
2495} /* bn_new() */
2496
2497
2498static int bn_fromBinary(lua_State *L) {
2499 size_t len;
2500 const char *s = luaL_checklstring(L, 1, &len);
2501 BIGNUM *bn = bn_push(L);
2502 if (!BN_bin2bn((const unsigned char*)s, len, bn)) {
2503 auxL_error(L, auxL_EOPENSSL, "bignum");
2504 }
2505 return 1;
2506} /* bn_fromBinary() */
2507
2508
2509static int bn_interpose(lua_State *L) {
2510 return interpose(L, BIGNUM_CLASS);
2511} /* bn_interpose() */
2512
2513
2514/* return integral part */
2515static inline double intof(double f) {
2516 return (isfinite(f))? floor(fabs(f)) : 0.0;
2517} /* intof() */
2518
2519
2520/* convert integral to BN_ULONG. returns success or failure. */
2521static _Bool int2ul(BN_ULONG *ul, double f) {
2522 int exp;
2523
2524 frexp(f, &exp);
2525
2526 if (exp > (int)sizeof *ul * 8)
2527 return 0;
2528
2529 *ul = (BN_ULONG)f;
2530
2531 return 1;
2532} /* int2ul() */
2533
2534
2535/* convert integral BIGNUM. returns success or failure. */
2536static _Bool int2bn(BIGNUM **bn, double q) {
2537 unsigned char nib[32], bin[32], *p;
2538 size_t i, n;
2539 double r;
2540
2541 p = nib;
2542
2543 while (q >= 1.0 && p < endof(nib)) {
2544 r = fmod(q, 256.0);
2545 *p++ = r;
2546 q = round((q - r) / 256.0);
2547 }
2548
2549 n = p - nib;
2550
2551 for (i = 0; i < n; i++) {
2552 bin[i] = *--p;
2553 }
2554
2555 if (!(*bn = BN_bin2bn(bin, n, *bn)))
2556 return 0;
2557
2558 return 1;
2559} /* int2bn() */
2560
2561
2562/* convert double to BIGNUM. returns success or failure. */
2563static _Bool f2bn(BIGNUM **bn, double f) {
2564 double i = intof(f);
2565 BN_ULONG lu;
2566
2567 if (int2ul(&lu, i)) {
2568 if (!*bn && !(*bn = BN_new()))
2569 return 0;
2570
2571 if (!BN_set_word(*bn, lu))
2572 return 0;
2573 } else if (!int2bn(bn, i))
2574 return 0;
2575
2576 BN_set_negative(*bn, signbit(f));
2577
2578 return 1;
2579} /* f2bn() */
2580
2581
2582static BIGNUM *(checkbig)(lua_State *L, int index, _Bool *lvalue) {
2583 BIGNUM **bn;
2584 const char *str;
2585 size_t len, i;
2586 _Bool neg, hex;
2587
2588 index = lua_absindex(L, index);
2589
2590 switch (lua_type(L, index)) {
2591 case LUA_TSTRING:
2592 *lvalue = 0;
2593
2594 str = lua_tolstring(L, index, &len);
2595
2596 neg = (str[0] == '-');
2597 hex = (str[neg] == '0' && (str[neg+1] == 'x' || str[neg+1] == 'X'));
2598
2599 if (hex) {
2600 luaL_argcheck(L, len > 2+(size_t)neg, index, "invalid hex string");
2601 for (i = 2+neg; i < len; i++) {
2602 if (!isxdigit((unsigned char)str[i]))
2603 luaL_argerror(L, 1, "invalid hex string");
2604 }
2605 } else {
2606 luaL_argcheck(L, len > neg, index, "invalid decimal string");
2607 for (i = neg; i < len; i++) {
2608 if (!isdigit((unsigned char)str[i]))
2609 luaL_argerror(L, 1, "invalid decimal string");
2610 }
2611 }
2612
2613 bn = prepsimple(L, BIGNUM_CLASS);
2614
2615 if (hex) {
2616 if (!BN_hex2bn(bn, str+2+neg))
2617 auxL_error(L, auxL_EOPENSSL, "bignum");
2618 if (neg)
2619 BN_set_negative(*bn, 1);
2620 } else {
2621 if (!BN_dec2bn(bn, str))
2622 auxL_error(L, auxL_EOPENSSL, "bignum");
2623 }
2624
2625 lua_replace(L, index);
2626
2627 return *bn;
2628 case LUA_TNUMBER:
2629 *lvalue = 0;
2630
2631 bn = prepsimple(L, BIGNUM_CLASS);
2632
2633 if (!f2bn(bn, lua_tonumber(L, index)))
2634 auxL_error(L, auxL_EOPENSSL, "bignum");
2635
2636 lua_replace(L, index);
2637
2638 return *bn;
2639 default:
2640 *lvalue = 1;
2641
2642 return checksimple(L, index, BIGNUM_CLASS);
2643 } /* switch() */
2644} /* checkbig() */
2645
2646
2647/* prepare number at top of stack for unary operation, and push result object onto stack */
2648static void bn_prepuop(lua_State *L, BIGNUM **r, BIGNUM **a, _Bool commute) {
2649 _Bool lvalue = 1;
2650
2651 *a = checkbig(L, -1, &lvalue);
2652
2653 if (!lvalue && commute) {
2654 lua_pushvalue(L, -1);
2655 } else {
2656 bn_push(L);
2657 }
2658
2659 *r = *(BIGNUM **)lua_touserdata(L, -1);
2660} /* bn_prepuop() */
2661
2662
2663/* prepare numbers at top of stack for binary operation, and push result object onto stack */
2664static void bn_prepbop(lua_State *L, BIGNUM **r, BIGNUM **a, BIGNUM **b, _Bool commute) {
2665 _Bool a_lvalue, b_lvalue;
2666
2667 *a = checkbig(L, -2, &a_lvalue);
2668 *b = checkbig(L, -1, &b_lvalue);
2669
2670 if (commute && !a_lvalue) {
2671 lua_pushvalue(L, -2);
2672 } else if (commute && !b_lvalue) {
2673 lua_pushvalue(L, -1);
2674 } else {
2675 bn_push(L);
2676 }
2677
2678 *r = *(BIGNUM **)lua_touserdata(L, -1);
2679} /* bn_prepbop() */
2680
2681
2682static int ctx__gc(lua_State *L) {
2683 BN_CTX **ctx = lua_touserdata(L, 1);
2684
2685 if (*ctx) {
2686 BN_CTX_free(*ctx);
2687 *ctx = NULL;
2688 }
2689
2690 return 0;
2691} /* ctx__gc() */
2692
2693static BN_CTX *getctx(lua_State *L) {
2694 BN_CTX **ctx;
2695
2696 lua_pushlightuserdata(L, (void *)&ctx__gc);
2697 lua_gettable(L, LUA_REGISTRYINDEX);
2698
2699 if (lua_isnil(L, -1)) {
2700 lua_pop(L, 1);
2701
2702 ctx = prepsimple(L, NULL, &ctx__gc);
2703
2704 if (!(*ctx = BN_CTX_new()))
2705 auxL_error(L, auxL_EOPENSSL, "bignum");
2706
2707 lua_pushlightuserdata(L, (void *)&ctx__gc);
2708 lua_pushvalue(L, -2);
2709 lua_settable(L, LUA_REGISTRYINDEX);
2710 }
2711
2712 ctx = lua_touserdata(L, -1);
2713 lua_pop(L, 1);
2714
2715 return *ctx;
2716} /* getctx() */
2717
2718
2719static int bn_toBinary(lua_State *L) {
2720 BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS);
2721 size_t len;
2722 void *dst;
2723
2724 len = BN_num_bytes(bn);
2725 dst = lua_newuserdata(L, len);
2726 BN_bn2bin(bn, dst);
2727 lua_pushlstring(L, dst, len);
2728
2729 return 1;
2730} /* bn_toBinary() */
2731
2732
2733static int bn__add(lua_State *L) {
2734 BIGNUM *r, *a, *b;
2735
2736 lua_settop(L, 2);
2737 bn_prepbop(L, &r, &a, &b, 1);
2738
2739 if (!BN_add(r, a, b))
2740 return auxL_error(L, auxL_EOPENSSL, "bignum:__add");
2741
2742 return 1;
2743} /* bn__add() */
2744
2745
2746static int bn__sub(lua_State *L) {
2747 BIGNUM *r, *a, *b;
2748
2749 lua_settop(L, 2);
2750 bn_prepbop(L, &r, &a, &b, 0);
2751
2752 if (!BN_sub(r, a, b))
2753 return auxL_error(L, auxL_EOPENSSL, "bignum:__sub");
2754
2755 return 1;
2756} /* bn__sub() */
2757
2758
2759static int bn__mul(lua_State *L) {
2760 BIGNUM *r, *a, *b;
2761
2762 lua_settop(L, 2);
2763 bn_prepbop(L, &r, &a, &b, 1);
2764
2765 if (!BN_mul(r, a, b, getctx(L)))
2766 return auxL_error(L, auxL_EOPENSSL, "bignum:__mul");
2767
2768 return 1;
2769} /* bn__mul() */
2770
2771
2772static int bn_sqr(lua_State *L) {
2773 BIGNUM *r, *a;
2774
2775 lua_settop(L, 1);
2776 bn_prepuop(L, &r, &a, 1);
2777
2778 if (!BN_sqr(r, a, getctx(L)))
2779 return auxL_error(L, auxL_EOPENSSL, "bignum:sqr");
2780
2781 return 1;
2782} /* bn_sqr() */
2783
2784
2785static int bn__idiv(lua_State *L) {
2786 BIGNUM *dv, *a, *b;
2787
2788 lua_settop(L, 2);
2789 bn_prepbop(L, &dv, &a, &b, 0);
2790
2791 if (!BN_div(dv, NULL, a, b, getctx(L)))
2792 return auxL_error(L, auxL_EOPENSSL, "bignum:__idiv");
2793
2794 return 1;
2795} /* bn__idiv() */
2796
2797
2798static int bn__mod(lua_State *L) {
2799 BIGNUM *r, *a, *b;
2800
2801 lua_settop(L, 2);
2802 bn_prepbop(L, &r, &a, &b, 0);
2803
2804 if (!BN_mod(r, a, b, getctx(L)))
2805 return auxL_error(L, auxL_EOPENSSL, "bignum:__mod");
2806
2807 /* lua has different rounding behaviour for mod than C */
2808 if (!BN_is_zero(r) && (BN_is_negative(a) ^ BN_is_negative(b))) {
2809 if (!BN_add(r, r, b))
2810 return auxL_error(L, auxL_EOPENSSL, "bignum:__mod");
2811 }
2812
2813 return 1;
2814} /* bn__mod() */
2815
2816
2817static int bn_nnmod(lua_State *L) {
2818 BIGNUM *r, *a, *b;
2819
2820 lua_settop(L, 2);
2821 bn_prepbop(L, &r, &a, &b, 0);
2822
2823 if (!BN_nnmod(r, a, b, getctx(L)))
2824 return auxL_error(L, auxL_EOPENSSL, "bignum:nnmod");
2825
2826 return 1;
2827} /* bn_nnmod() */
2828
2829
2830static int bn__pow(lua_State *L) {
2831 BIGNUM *r, *a, *b;
2832
2833 lua_settop(L, 2);
2834 bn_prepbop(L, &r, &a, &b, 0);
2835
2836 if (!BN_exp(r, a, b, getctx(L)))
2837 return auxL_error(L, auxL_EOPENSSL, "bignum:__pow");
2838
2839 return 1;
2840} /* bn__pow() */
2841
2842
2843static int bn_gcd(lua_State *L) {
2844 BIGNUM *r, *a, *b;
2845
2846 lua_settop(L, 2);
2847 bn_prepbop(L, &r, &a, &b, 1);
2848
2849 if (!BN_gcd(r, a, b, getctx(L)))
2850 return auxL_error(L, auxL_EOPENSSL, "bignum:gcd");
2851
2852 return 1;
2853} /* bn_gcd() */
2854
2855
2856static int bn__shl(lua_State *L) {
2857 BIGNUM *r, *a;
2858 int n;
2859
2860 a = checkbig(L, 1);
2861 n = luaL_checkinteger(L, 2);
2862 r = bn_push(L);
2863
2864 if (!BN_lshift(r, a, n))
2865 return auxL_error(L, auxL_EOPENSSL, "bignum:__shl");
2866
2867 return 1;
2868} /* bn__shl() */
2869
2870
2871static int bn__shr(lua_State *L) {
2872 BIGNUM *r, *a;
2873 int n;
2874
2875 a = checkbig(L, 1);
2876 n = luaL_checkinteger(L, 2);
2877 r = bn_push(L);
2878
2879 if (!BN_rshift(r, a, n))
2880 return auxL_error(L, auxL_EOPENSSL, "bignum:__shr");
2881
2882 return 1;
2883} /* bn__shr() */
2884
2885
2886static int bn__unm(lua_State *L) {
2887 BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS);
2888 BIGNUM *r = bn_dup(L, a);
2889
2890 BN_set_negative(r, !BN_is_negative(a));
2891
2892 return 1;
2893} /* bn__unm() */
2894
2895
2896static int bn__eq(lua_State *L) {
2897 BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS);
2898 BIGNUM *b = checksimple(L, 2, BIGNUM_CLASS);
2899
2900 lua_pushboolean(L, 0 == BN_cmp(a, b));
2901
2902 return 1;
2903} /* bn__eq() */
2904
2905
2906static int bn__lt(lua_State *L) {
2907 BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS);
2908 BIGNUM *b = checksimple(L, 2, BIGNUM_CLASS);
2909 int cmp = BN_cmp(a, b);
2910
2911 lua_pushboolean(L, cmp == -1);
2912
2913 return 1;
2914} /* bn__lt() */
2915
2916
2917static int bn__le(lua_State *L) {
2918 BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS);
2919 BIGNUM *b = checksimple(L, 2, BIGNUM_CLASS);
2920 int cmp = BN_cmp(a, b);
2921
2922 lua_pushboolean(L, cmp <= 0);
2923
2924 return 1;
2925} /* bn__le() */
2926
2927
2928static int bn__gc(lua_State *L) {
2929 BIGNUM **ud = luaL_checkudata(L, 1, BIGNUM_CLASS);
2930
2931 if (*ud) {
2932 BN_clear_free(*ud);
2933 *ud = NULL;
2934 }
2935
2936 return 0;
2937} /* bn__gc() */
2938
2939
2940static int bn_generatePrime(lua_State *L) {
2941 int bits = luaL_checkinteger(L, 1);
2942 _Bool safe = optbool(L, 2, 0);
2943 const BIGNUM *add = lua_isnoneornil(L, 3) ? NULL : checkbig(L, 3);
2944 const BIGNUM *rem = lua_isnoneornil(L, 4) ? NULL : checkbig(L, 4);
2945 BIGNUM *bn = bn_push(L);
2946
2947 if (!BN_generate_prime_ex(bn, bits, safe, add, rem, NULL))
2948 return auxL_error(L, auxL_EOPENSSL, "bignum.generatePrime");
2949
2950 return 1;
2951} /* bn_generatePrime() */
2952
2953
2954static int bn_isPrime(lua_State *L) {
2955 BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS);
2956 int nchecks = luaL_optinteger(L, 2, BN_prime_checks);
2957 int res = BN_is_prime_ex(bn, nchecks, getctx(L), NULL);
2958
2959 if (res == -1)
2960 return auxL_error(L, auxL_EOPENSSL, "bignum:isPrime");
2961
2962 lua_pushboolean(L, res);
2963
2964 return 1;
2965} /* bn_isPrime() */
2966
2967
2968static BIO *getbio(lua_State *);
2969
2970static int bn_toDecimal(lua_State *L) {
2971 BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS);
2972 char *txt = NULL;
2973 BIO *bio;
2974 BUF_MEM *buf;
2975
2976 if (!(txt = BN_bn2dec(bn)))
2977 goto sslerr;
2978
2979 /* use GC-visible BIO as temporary buffer */
2980 bio = getbio(L);
2981
2982 if (BIO_puts(bio, txt) < 0)
2983 goto sslerr;
2984
2985 OPENSSL_free(txt);
2986 txt = NULL;
2987
2988 BIO_get_mem_ptr(bio, &buf);
2989 lua_pushlstring(L, buf->data, buf->length);
2990
2991 return 1;
2992sslerr:
2993 OPENSSL_free(txt);
2994
2995 return auxL_error(L, auxL_EOPENSSL, "bignum:toDecimal");
2996} /* bn_toDecimal() */
2997
2998
2999static int bn_toHex(lua_State *L) {
3000 BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS);
3001 char *txt = NULL;
3002 BIO *bio;
3003 BUF_MEM *buf;
3004
3005 if (!(txt = BN_bn2hex(bn)))
3006 goto sslerr;
3007
3008 /* use GC-visible BIO as temporary buffer */
3009 bio = getbio(L);
3010
3011 if (BIO_puts(bio, txt) < 0)
3012 goto sslerr;
3013
3014 OPENSSL_free(txt);
3015 txt = NULL;
3016
3017 BIO_get_mem_ptr(bio, &buf);
3018 lua_pushlstring(L, buf->data, buf->length);
3019
3020 return 1;
3021sslerr:
3022 OPENSSL_free(txt);
3023
3024 return auxL_error(L, auxL_EOPENSSL, "bignum:toHex");
3025} /* bn_toHex() */
3026
3027
3028static const auxL_Reg bn_methods[] = {
3029 { "add", &bn__add },
3030 { "sub", &bn__sub },
3031 { "mul", &bn__mul },
3032 { "sqr", &bn_sqr },
3033 { "idiv", &bn__idiv },
3034 { "mod", &bn__mod },
3035 { "nnmod", &bn_nnmod },
3036 { "exp", &bn__pow },
3037 { "gcd", &bn_gcd },
3038 { "lshift", &bn__shl },
3039 { "rshift", &bn__shr },
3040 { "isPrime", &bn_isPrime },
3041 { "toBinary", &bn_toBinary },
3042 { "toDecimal", &bn_toDecimal },
3043 { "toHex", &bn_toHex },
3044 /* deprecated */
3045 { "tobin", &bn_toBinary },
3046 { "todec", &bn_toDecimal },
3047 { "tohex", &bn_toHex },
3048 { NULL, NULL },
3049};
3050
3051static const auxL_Reg bn_metatable[] = {
3052 { "__add", &bn__add },
3053 { "__sub", &bn__sub },
3054 { "__mul", &bn__mul },
3055 { "__div", &bn__idiv },
3056 { "__idiv", &bn__idiv },
3057 { "__mod", &bn__mod },
3058 { "__pow", &bn__pow },
3059 { "__unm", &bn__unm },
3060 { "__shl", &bn__shl },
3061 { "__shr", &bn__shr },
3062 { "__eq", &bn__eq },
3063 { "__lt", &bn__lt },
3064 { "__le", &bn__le },
3065 { "__gc", &bn__gc },
3066 { "__tostring", &bn_toDecimal },
3067 { NULL, NULL },
3068};
3069
3070
3071static const auxL_Reg bn_globals[] = {
3072 { "new", &bn_new },
3073 { "interpose", &bn_interpose },
3074 { "fromBinary", &bn_fromBinary },
3075 { "generatePrime", &bn_generatePrime },
3076 { NULL, NULL },
3077};
3078
3079int luaopen__openssl_bignum(lua_State *L) {
3080 initall(L);
3081
3082 auxL_newlib(L, bn_globals, 0);
3083
3084 return 1;
3085} /* luaopen__openssl_bignum() */
3086
3087
3088/*
3089 * EVP_PKEY - openssl.pkey
3090 *
3091 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
3092
3093static int bio__gc(lua_State *L) {
3094 BIO **bio = lua_touserdata(L, 1);
3095
3096 if (*bio) {
3097 BIO_free(*bio);
3098 *bio = NULL;
3099 }
3100
3101 return 0;
3102} /* bio__gc() */
3103
3104static BIO *getbio(lua_State *L) {
3105 BIO **bio;
3106
3107 lua_pushlightuserdata(L, (void *)&bio__gc);
3108 lua_gettable(L, LUA_REGISTRYINDEX);
3109
3110 if (lua_isnil(L, -1)) {
3111 lua_pop(L, 1);
3112
3113 bio = prepsimple(L, NULL, &bio__gc);
3114
3115 if (!(*bio = BIO_new(BIO_s_mem())))
3116 auxL_error(L, auxL_EOPENSSL, "BIO_new");
3117
3118 lua_pushlightuserdata(L, (void *)&bio__gc);
3119 lua_pushvalue(L, -2);
3120 lua_settable(L, LUA_REGISTRYINDEX);
3121 }
3122
3123 bio = lua_touserdata(L, -1);
3124 lua_pop(L, 1);
3125
3126 BIO_reset(*bio);
3127
3128 return *bio;
3129} /* getbio() */
3130
3131
3132static int pk_new(lua_State *L) {
3133 EVP_PKEY **ud;
3134
3135 /* #1 table or key; if key, #2 format and #3 type */
3136 lua_settop(L, 3);
3137
3138 ud = prepsimple(L, PKEY_CLASS);
3139
3140 if (lua_istable(L, 1) || lua_isnil(L, 1)) {
3141 int type = EVP_PKEY_RSA;
3142 unsigned bits = 1024;
3143 unsigned exp = 65537;
3144 int curve = NID_X9_62_prime192v1;
3145 const char *id;
3146 const char *dhparam = NULL;
3147 lua_Number n;
3148
3149 if (!lua_istable(L, 1))
3150 goto creat;
3151
3152 if (loadfield(L, 1, "type", LUA_TSTRING, &id)) {
3153 static const struct { int nid; const char *sn; } types[] = {
3154 { EVP_PKEY_RSA, "RSA" },
3155 { EVP_PKEY_DSA, "DSA" },
3156 { EVP_PKEY_DH, "DH" },
3157 { EVP_PKEY_EC, "EC" },
3158 };
3159 unsigned i;
3160
3161 if (NID_undef == (type = EVP_PKEY_type(OBJ_sn2nid(id)))) {
3162 for (i = 0; i < countof(types); i++) {
3163 if (strieq(id, types[i].sn)) {
3164 type = types[i].nid;
3165 break;
3166 }
3167 }
3168 }
3169
3170 luaL_argcheck(L, type != NID_undef, 1, lua_pushfstring(L, "%s: invalid key type", id));
3171 }
3172
3173 if (loadfield(L, 1, "bits", LUA_TNUMBER, &n)) {
3174 luaL_argcheck(L, n > 0 && n < UINT_MAX, 1, lua_pushfstring(L, "%f: `bits' invalid", n));
3175 bits = (unsigned)n;
3176 }
3177
3178 if (loadfield(L, 1, "exp", LUA_TNUMBER, &n)) {
3179 luaL_argcheck(L, n > 0 && n < UINT_MAX, 1, lua_pushfstring(L, "%f: `exp' invalid", n));
3180 exp = (unsigned)n;
3181 }
3182
3183 if (loadfield(L, 1, "curve", LUA_TSTRING, &id)) {
3184 if (!auxS_txt2nid(&curve, id))
3185 luaL_argerror(L, 1, lua_pushfstring(L, "%s: invalid curve", id));
3186 }
3187
3188 /* dhparam field can contain a PEM encoded string. */
3189 loadfield(L, 1, "dhparam", LUA_TSTRING, &dhparam);
3190
3191creat:
3192 if (!(*ud = EVP_PKEY_new()))
3193 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3194
3195 switch (EVP_PKEY_type(type)) {
3196 case EVP_PKEY_RSA: {
3197 RSA *rsa;
3198
3199 if (!(rsa = RSA_generate_key(bits, exp, 0, 0)))
3200 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3201
3202 EVP_PKEY_set1_RSA(*ud, rsa);
3203
3204 RSA_free(rsa);
3205
3206 break;
3207 }
3208 case EVP_PKEY_DSA: {
3209 DSA *dsa;
3210
3211 if (!(dsa = DSA_generate_parameters(bits, 0, 0, 0, 0, 0, 0)))
3212 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3213
3214 if (!DSA_generate_key(dsa)) {
3215 DSA_free(dsa);
3216 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3217 }
3218
3219 EVP_PKEY_set1_DSA(*ud, dsa);
3220
3221 DSA_free(dsa);
3222
3223 break;
3224 }
3225 case EVP_PKEY_DH: {
3226 DH *dh;
3227
3228 /* DH Parameter Generation can take a long time, therefore we look
3229 * at the "dhparam" field, provided by the user.
3230 * The "dhparam" field takes precedence over "bits"
3231 */
3232 if (dhparam) {
3233 BIO *bio = BIO_new_mem_buf((void*)dhparam, strlen(dhparam));
3234 if (!bio)
3235 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3236
3237 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3238 BIO_free(bio);
3239 if (!dh)
3240 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3241 } else if (!(dh = DH_generate_parameters(bits, exp, 0, 0)))
3242 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3243
3244
3245 if (!DH_generate_key(dh)) {
3246 DH_free(dh);
3247 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3248 }
3249
3250 EVP_PKEY_set1_DH(*ud, dh);
3251
3252 DH_free(dh);
3253
3254 break;
3255 }
3256#ifndef OPENSSL_NO_EC
3257 case EVP_PKEY_EC: {
3258 EC_GROUP *grp;
3259 EC_KEY *key;
3260
3261 if (!(grp = EC_GROUP_new_by_curve_name(curve)))
3262 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3263
3264 EC_GROUP_set_asn1_flag(grp, OPENSSL_EC_NAMED_CURVE);
3265
3266 /* compressed points patented */
3267 EC_GROUP_set_point_conversion_form(grp, POINT_CONVERSION_UNCOMPRESSED);
3268
3269 if (!(key = EC_KEY_new())) {
3270 EC_GROUP_free(grp);
3271 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3272 }
3273
3274 EC_KEY_set_group(key, grp);
3275
3276 EC_GROUP_free(grp);
3277
3278 if (!EC_KEY_generate_key(key)) {
3279 EC_KEY_free(key);
3280 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3281 }
3282
3283 EVP_PKEY_set1_EC_KEY(*ud, key);
3284
3285 EC_KEY_free(key);
3286
3287 break;
3288 }
3289#endif
3290 default:
3291 return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_type(type));
3292 } /* switch() */
3293 } else if (lua_isstring(L, 1)) {
3294 int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER);
3295 int pubonly = 0, prvtonly = 0;
3296 const char *opt, *data;
3297 size_t len;
3298 BIO *bio;
3299 EVP_PKEY *pub = NULL, *prvt = NULL;
3300 int goterr = 0;
3301
3302 /* check if specified publickey or privatekey */
3303 if ((opt = luaL_optstring(L, 3, NULL))) {
3304 if (xtolower(opt[0]) == 'p' && xtolower(opt[1]) == 'u') {
3305 pubonly = 1;
3306 } else if (xtolower(opt[0]) == 'p' && xtolower(opt[1]) == 'r') {
3307 prvtonly = 1;
3308 } else {
3309 return luaL_argerror(L, 3, lua_pushfstring(L, "invalid option %s", opt));
3310 }
3311 }
3312
3313 data = luaL_checklstring(L, 1, &len);
3314
3315 if (!(bio = BIO_new_mem_buf((void *)data, len)))
3316 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3317
3318 if (type == X509_PEM || type == X509_ANY) {
3319 if (!prvtonly && !pub) {
3320 /*
3321 * BIO_reset is a rewind for read-only
3322 * memory buffers. See mem_ctrl in
3323 * crypto/bio/bss_mem.c of OpenSSL source.
3324 */
3325 BIO_reset(bio);
3326
3327 if (!(pub = PEM_read_bio_PUBKEY(bio, NULL, 0, "")))
3328 goterr = 1;
3329 }
3330
3331 if (!pubonly && !prvt) {
3332 BIO_reset(bio);
3333
3334 if (!(prvt = PEM_read_bio_PrivateKey(bio, NULL, 0, "")))
3335 goterr = 1;
3336 }
3337 }
3338
3339 if (type == X509_DER || type == X509_ANY) {
3340 if (!prvtonly && !pub) {
3341 BIO_reset(bio);
3342
3343 if (!(pub = d2i_PUBKEY_bio(bio, NULL)))
3344 goterr = 1;
3345 }
3346
3347 if (!pubonly && !prvt) {
3348 BIO_reset(bio);
3349
3350 if (!(prvt = d2i_PrivateKey_bio(bio, NULL)))
3351 goterr = 1;
3352 }
3353 }
3354
3355 if (prvt) {
3356#if 0
3357 /* TODO: Determine if this is necessary. */
3358 if (pub && EVP_PKEY_missing_parameters(prvt)) {
3359 if (!EVP_PKEY_copy_parameters(prvt, pub)) {
3360 /*
3361 * NOTE: It's not necessarily true
3362 * that any internal errors were
3363 * set. But we fixed pusherror() to
3364 * handle that situation.
3365 */
3366 goterr = 1;
3367
3368 goto done;
3369 }
3370 }
3371#endif
3372
3373 *ud = prvt;
3374 prvt = NULL;
3375 } else if (pub) {
3376 *ud = pub;
3377 pub = NULL;
3378 }
3379done:
3380 BIO_free(bio);
3381
3382 if (pub)
3383 EVP_PKEY_free(pub);
3384
3385 if (prvt)
3386 EVP_PKEY_free(prvt);
3387
3388 if (!*ud) {
3389 if (goterr)
3390 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3391
3392 /* we should never get here */
3393 return luaL_error(L, "failed to load key for some unexpected reason");
3394 } else if (goterr) {
3395 /* clean up our mess from testing input formats */
3396 ERR_clear_error();
3397 }
3398 } else {
3399 return luaL_error(L, "%s: unknown key initializer", lua_typename(L, lua_type(L, 1)));
3400 }
3401
3402 return 1;
3403} /* pk_new() */
3404
3405
3406static int pk_interpose(lua_State *L) {
3407 lua_settop(L, 2);
3408
3409 luaL_getmetatable(L, PKEY_CLASS);
3410 if (!strncmp("__", luaL_checkstring(L, 1), 2)) {
3411 lua_insert(L, 1);
3412 } else {
3413 lua_getfield(L, -1, "__index");
3414 lua_getupvalue(L, -1, 1);
3415 lua_insert(L, 1);
3416 lua_pop(L, 2);
3417 }
3418
3419 return auxL_swaptable(L, 1);
3420} /* pk_interpose() */
3421
3422
3423static int pk_type(lua_State *L) {
3424 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
3425 int nid = EVP_PKEY_id(key);
3426
3427 auxL_pushnid(L, nid);
3428
3429 return 1;
3430} /* pk_type() */
3431
3432
3433static int pk_setPublicKey(lua_State *L) {
3434 EVP_PKEY **key = luaL_checkudata(L, 1, PKEY_CLASS);
3435 const char *data;
3436 size_t len;
3437 BIO *bio;
3438 int type, ok = 0;
3439
3440 data = luaL_checklstring(L, 2, &len);
3441 type = optencoding(L, 3, "*", X509_ANY|X509_PEM|X509_DER);
3442
3443 if (!(bio = BIO_new_mem_buf((void *)data, len)))
3444 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3445
3446 if (type == X509_ANY || type == X509_PEM) {
3447 ok = !!PEM_read_bio_PUBKEY(bio, key, 0, "");
3448 }
3449
3450 if (!ok && (type == X509_ANY || type == X509_DER)) {
3451 ok = !!d2i_PUBKEY_bio(bio, key);
3452 }
3453
3454 BIO_free(bio);
3455
3456 if (!ok)
3457 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3458
3459 lua_pushboolean(L, 1);
3460
3461 return 1;
3462} /* pk_setPublicKey() */
3463
3464
3465static int pk_setPrivateKey(lua_State *L) {
3466 EVP_PKEY **key = luaL_checkudata(L, 1, PKEY_CLASS);
3467 const char *data;
3468 size_t len;
3469 BIO *bio;
3470 int type, ok = 0;
3471
3472 data = luaL_checklstring(L, 2, &len);
3473 type = optencoding(L, 3, "*", X509_ANY|X509_PEM|X509_DER);
3474
3475 if (!(bio = BIO_new_mem_buf((void *)data, len)))
3476 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3477
3478 if (type == X509_ANY || type == X509_PEM) {
3479 ok = !!PEM_read_bio_PrivateKey(bio, key, 0, "");
3480 }
3481
3482 if (!ok && (type == X509_ANY || type == X509_DER)) {
3483 ok = !!d2i_PrivateKey_bio(bio, key);
3484 }
3485
3486 BIO_free(bio);
3487
3488 if (!ok)
3489 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3490
3491 lua_pushboolean(L, 1);
3492
3493 return 1;
3494} /* pk_setPrivateKey() */
3495
3496#if HAVE_EVP_PKEY_CTX_NEW
3497static int pk_decrypt(lua_State *L) {
3498 size_t outlen, inlen;
3499 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
3500 EVP_PKEY_CTX *ctx;
3501 const char *str = luaL_checklstring(L, 2, &inlen);
3502 BIO *bio;
3503 BUF_MEM *buf;
3504 int rsaPadding = RSA_PKCS1_PADDING; /* default for `openssl rsautl` */
3505 int base_type = EVP_PKEY_base_id(key);
3506
3507 if (lua_istable(L, 3)) {
3508 if (base_type == EVP_PKEY_RSA) {
3509 lua_getfield(L, 3, "rsaPadding");
3510 rsaPadding = luaL_optinteger(L, -1, rsaPadding);
3511 lua_pop(L, 1);
3512 }
3513 }
3514
3515 bio = getbio(L);
3516 BIO_get_mem_ptr(bio, &buf);
3517
3518 if (!(ctx = EVP_PKEY_CTX_new(key, NULL)))
3519 goto sslerr;
3520
3521 if (EVP_PKEY_decrypt_init(ctx) <= 0)
3522 goto sslerr;
3523
3524 if (base_type == EVP_PKEY_RSA && !EVP_PKEY_CTX_set_rsa_padding(ctx, rsaPadding))
3525 goto sslerr;
3526
3527 if (EVP_PKEY_decrypt(ctx, NULL, &outlen, (const unsigned char *)str, inlen) <= 0)
3528 goto sslerr;
3529
3530 if (!BUF_MEM_grow_clean(buf, outlen))
3531 goto sslerr;
3532
3533 if (EVP_PKEY_decrypt(ctx, (unsigned char *)buf->data, &outlen, (const unsigned char *)str, inlen) <= 0)
3534 goto sslerr;
3535
3536 EVP_PKEY_CTX_free(ctx);
3537 ctx = NULL;
3538
3539 lua_pushlstring(L, buf->data, outlen);
3540
3541 BIO_reset(bio);
3542
3543 return 1;
3544sslerr:
3545 if (ctx) {
3546 EVP_PKEY_CTX_free(ctx);
3547 ctx = NULL;
3548 }
3549 BIO_reset(bio);
3550
3551 return auxL_error(L, auxL_EOPENSSL, "pkey:decrypt");
3552} /* pk_decrypt() */
3553#endif
3554
3555#if HAVE_EVP_PKEY_CTX_NEW
3556static int pk_encrypt(lua_State *L) {
3557 size_t outlen, inlen;
3558 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
3559 EVP_PKEY_CTX *ctx;
3560 const char *str = luaL_checklstring(L, 2, &inlen);
3561 BIO *bio;
3562 BUF_MEM *buf;
3563 int rsaPadding = RSA_PKCS1_PADDING; /* default for `openssl rsautl` */
3564 int base_type = EVP_PKEY_base_id(key);
3565
3566 if (lua_istable(L, 3)) {
3567 if (base_type == EVP_PKEY_RSA) {
3568 lua_getfield(L, 3, "rsaPadding");
3569 rsaPadding = luaL_optinteger(L, -1, rsaPadding);
3570 lua_pop(L, 1);
3571 }
3572 }
3573
3574 bio = getbio(L);
3575 BIO_get_mem_ptr(bio, &buf);
3576
3577 if (!(ctx = EVP_PKEY_CTX_new(key, NULL)))
3578 goto sslerr;
3579
3580 if (EVP_PKEY_encrypt_init(ctx) <= 0)
3581 goto sslerr;
3582
3583 if (base_type == EVP_PKEY_RSA && !EVP_PKEY_CTX_set_rsa_padding(ctx, rsaPadding))
3584 goto sslerr;
3585
3586 if (EVP_PKEY_encrypt(ctx, NULL, &outlen, (const unsigned char *)str, inlen) <= 0)
3587 goto sslerr;
3588
3589 if (!BUF_MEM_grow_clean(buf, outlen))
3590 goto sslerr;
3591
3592 if (EVP_PKEY_encrypt(ctx, (unsigned char *)buf->data, &outlen, (const unsigned char *)str, inlen) <= 0)
3593 goto sslerr;
3594
3595 EVP_PKEY_CTX_free(ctx);
3596 ctx = NULL;
3597
3598 lua_pushlstring(L, buf->data, outlen);
3599
3600 BIO_reset(bio);
3601
3602 return 1;
3603sslerr:
3604 if (ctx) {
3605 EVP_PKEY_CTX_free(ctx);
3606 ctx = NULL;
3607 }
3608 BIO_reset(bio);
3609
3610 return auxL_error(L, auxL_EOPENSSL, "pkey:encrypt");
3611} /* pk_encrypt() */
3612#endif
3613
3614static int pk_sign(lua_State *L) {
3615 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
3616 EVP_MD_CTX *md = checksimple(L, 2, DIGEST_CLASS);
3617 luaL_Buffer B;
3618 unsigned n;
3619
3620 if (LUAL_BUFFERSIZE < EVP_PKEY_size(key))
3621 return luaL_error(L, "pkey:sign: LUAL_BUFFERSIZE(%u) < EVP_PKEY_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)EVP_PKEY_size(key));
3622
3623 luaL_buffinit(L, &B);
3624 n = LUAL_BUFFERSIZE;
3625
3626 if (!EVP_SignFinal(md, (void *)luaL_prepbuffer(&B), &n, key))
3627 return auxL_error(L, auxL_EOPENSSL, "pkey:sign");
3628
3629 luaL_addsize(&B, n);
3630 luaL_pushresult(&B);
3631
3632 return 1;
3633} /* pk_sign() */
3634
3635
3636static int pk_verify(lua_State *L) {
3637 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
3638 size_t len;
3639 const void *sig = luaL_checklstring(L, 2, &len);
3640 EVP_MD_CTX *md = checksimple(L, 3, DIGEST_CLASS);
3641
3642 switch (EVP_VerifyFinal(md, sig, len, key)) {
3643 case 0: /* WRONG */
3644 ERR_clear_error();
3645 lua_pushboolean(L, 0);
3646
3647 break;
3648 case 1: /* OK */
3649 lua_pushboolean(L, 1);
3650
3651 break;
3652 default:
3653 return auxL_error(L, auxL_EOPENSSL, "pkey:verify");
3654 }
3655
3656 return 1;
3657} /* pk_verify() */
3658
3659
3660static int pk_toPEM(lua_State *L) {
3661 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
3662 int top, i, ok;
3663 BIO *bio;
3664 char *pem;
3665 long len;
3666
3667 if (1 == (top = lua_gettop(L))) {
3668 lua_pushstring(L, "publickey");
3669 ++top;
3670 }
3671
3672 bio = getbio(L);
3673
3674 for (i = 2; i <= top; i++) {
3675 static const char *const opts[] = {
3676 "public", "PublicKey",
3677 "private", "PrivateKey",
3678// "params", "Parameters",
3679 NULL,
3680 };
3681
3682 switch (auxL_checkoption(L, i, NULL, opts, 1)) {
3683 case 0: case 1: /* public, PublicKey */
3684 if (!PEM_write_bio_PUBKEY(bio, key))
3685 return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring");
3686
3687 len = BIO_get_mem_data(bio, &pem);
3688 lua_pushlstring(L, pem, len);
3689 BIO_reset(bio);
3690
3691 break;
3692 case 2: case 3: /* private, PrivateKey */
3693 if (!PEM_write_bio_PrivateKey(bio, key, 0, 0, 0, 0, 0))
3694 return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring");
3695
3696 len = BIO_get_mem_data(bio, &pem);
3697 lua_pushlstring(L, pem, len);
3698 BIO_reset(bio);
3699
3700 break;
3701#if 0
3702 case 4: case 5: /* params, Parameters */
3703 /* EVP_PKEY_base_id not in OS X */
3704 switch (EVP_PKEY_base_id(key)) {
3705 case EVP_PKEY_RSA:
3706 break;
3707 case EVP_PKEY_DSA: {
3708 DSA *dsa = EVP_PKEY_get1_DSA(key);
3709
3710 ok = !!PEM_write_bio_DSAparams(bio, dsa);
3711
3712 DSA_free(dsa);
3713
3714 if (!ok)
3715 return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring");
3716
3717 break;
3718 }
3719 case EVP_PKEY_DH: {
3720 DH *dh = EVP_PKEY_get1_DH(key);
3721
3722 ok = !!PEM_write_bio_DHparams(bio, dh);
3723
3724 DH_free(dh);
3725
3726 if (!ok)
3727 return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring");
3728
3729 break;
3730 }
3731#ifndef OPENSSL_NO_EC
3732 case EVP_PKEY_EC: {
3733 EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key);
3734 const EC_GROUP *grp = EC_KEY_get0_group(ec);
3735
3736 ok = !!PEM_write_bio_ECPKParameters(bio, grp);
3737
3738 EC_KEY_free(ec);
3739
3740 if (!ok)
3741 return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring");
3742
3743 break;
3744 }
3745#endif
3746 default:
3747 return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_base_id(key));
3748 }
3749
3750 lua_pushlstring(L, pem, len);
3751
3752 BIO_reset(bio);
3753
3754 break;
3755#endif
3756 default:
3757 lua_pushnil(L);
3758
3759 break;
3760 } /* switch() */
3761 } /* for() */
3762
3763 return lua_gettop(L) - top;
3764} /* pk_toPEM() */
3765
3766
3767static int pk_getDefaultDigestName(lua_State *L) {
3768 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
3769 int nid;
3770
3771 if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0))
3772 return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName");
3773
3774 auxL_pushnid(L, nid);
3775
3776 return 1;
3777} /* pk_getDefaultDigestName() */
3778
3779
3780enum pk_param {
3781#define PK_RSA_OPTLIST { "n", "e", "d", "p", "q", "dmp1", "dmq1", "iqmp", NULL }
3782#define PK_RSA_OPTOFFSET PK_RSA_N
3783 PK_RSA_N = 1,
3784 PK_RSA_E,
3785 PK_RSA_D,
3786 PK_RSA_P,
3787 PK_RSA_Q,
3788 PK_RSA_DMP1,
3789 PK_RSA_DMQ1,
3790 PK_RSA_IQMP,
3791
3792#define PK_DSA_OPTLIST { "p", "q", "g", "pub_key", "priv_key", NULL }
3793#define PK_DSA_OPTOFFSET PK_DSA_P
3794 PK_DSA_P,
3795 PK_DSA_Q,
3796 PK_DSA_G,
3797 PK_DSA_PUB_KEY,
3798 PK_DSA_PRIV_KEY,
3799
3800#define PK_DH_OPTLIST { "p", "g", "pub_key", "priv_key", NULL }
3801#define PK_DH_OPTOFFSET PK_DH_P
3802 PK_DH_P,
3803 PK_DH_G,
3804 PK_DH_PUB_KEY,
3805 PK_DH_PRIV_KEY,
3806
3807/*
3808 * NB: group MUST come before pub_key as setting pub_key requires the group
3809 * to be defined. :setParameters will do the requested assignments in the
3810 * order defined by this array.
3811 */
3812#define PK_EC_OPTLIST { "group", "pub_key", "priv_key", NULL }
3813#define PK_EC_OPTOFFSET PK_EC_GROUP
3814 PK_EC_GROUP,
3815 PK_EC_PUB_KEY,
3816 PK_EC_PRIV_KEY,
3817}; /* enum pk_param */
3818
3819static const char *const pk_rsa_optlist[] = PK_RSA_OPTLIST;
3820static const char *const pk_dsa_optlist[] = PK_DSA_OPTLIST;
3821static const char *const pk_dh_optlist[] = PK_DH_OPTLIST;
3822static const char *const pk_ec_optlist[] = PK_EC_OPTLIST;
3823
3824const char *const *pk_getoptlist(int type, int *_nopts, int *_optoffset) {
3825 const char *const *optlist = NULL;
3826 int nopts = 0, optoffset = 0;
3827
3828 switch (type) {
3829 case EVP_PKEY_RSA:
3830 optlist = pk_rsa_optlist;
3831 nopts = countof(pk_rsa_optlist) - 1;
3832 optoffset = PK_RSA_OPTOFFSET;
3833
3834 break;
3835 case EVP_PKEY_DSA:
3836 optlist = pk_dsa_optlist;
3837 nopts = countof(pk_dsa_optlist) - 1;
3838 optoffset = PK_DSA_OPTOFFSET;
3839
3840 break;
3841 case EVP_PKEY_DH:
3842 optlist = pk_dh_optlist;
3843 nopts = countof(pk_dh_optlist) - 1;
3844 optoffset = PK_DH_OPTOFFSET;
3845
3846 break;
3847 case EVP_PKEY_EC:
3848 optlist = pk_ec_optlist;
3849 nopts = countof(pk_ec_optlist) - 1;
3850 optoffset = PK_EC_OPTOFFSET;
3851
3852 break;
3853 }
3854
3855 if (_nopts)
3856 *_nopts = nopts;
3857 if (_optoffset)
3858 *_optoffset = optoffset;
3859
3860 return optlist;
3861} /* pk_getoptlist() */
3862
3863#ifndef OPENSSL_NO_EC
3864static EC_GROUP *ecg_dup_nil(lua_State *, const EC_GROUP *);
3865#endif
3866
3867static void pk_pushparam(lua_State *L, void *base_key, enum pk_param which) {
3868 union {
3869 RSA *rsa;
3870 DH *dh;
3871 DSA *dsa;
3872#ifndef OPENSSL_NO_EC
3873 EC_KEY *ec;
3874#endif
3875 } key = { base_key };
3876 const BIGNUM *i;
3877
3878 switch (which) {
3879 case PK_RSA_N:
3880 /* RSA public modulus n */
3881 RSA_get0_key(key.rsa, &i, NULL, NULL);
3882 bn_dup_nil(L, i);
3883
3884 break;
3885 case PK_RSA_E:
3886 /* RSA public exponent e */
3887 RSA_get0_key(key.rsa, NULL, &i, NULL);
3888 bn_dup_nil(L, i);
3889
3890 break;
3891 case PK_RSA_D:
3892 /* RSA secret exponent d */
3893 RSA_get0_key(key.rsa, NULL, NULL, &i);
3894 bn_dup_nil(L, i);
3895
3896 break;
3897 case PK_RSA_P:
3898 /* RSA secret prime p */
3899 RSA_get0_factors(key.rsa, &i, NULL);
3900 bn_dup_nil(L, i);
3901
3902 break;
3903 case PK_RSA_Q:
3904 /* RSA secret prime q with p < q */
3905 RSA_get0_factors(key.rsa, NULL, &i);
3906 bn_dup_nil(L, i);
3907
3908 break;
3909 case PK_RSA_DMP1:
3910 /* exponent1 */
3911 RSA_get0_crt_params(key.rsa, &i, NULL, NULL);
3912 bn_dup_nil(L, i);
3913
3914 break;
3915 case PK_RSA_DMQ1:
3916 /* exponent2 */
3917 RSA_get0_crt_params(key.rsa, NULL, &i, NULL);
3918 bn_dup_nil(L, i);
3919
3920 break;
3921 case PK_RSA_IQMP:
3922 /* coefficient */
3923 RSA_get0_crt_params(key.rsa, NULL, NULL, &i);
3924 bn_dup_nil(L, i);
3925
3926 break;
3927 case PK_DSA_P:
3928 DSA_get0_pqg(key.dsa, &i, NULL, NULL);
3929 bn_dup_nil(L, i);
3930
3931 break;
3932 case PK_DSA_Q:
3933 DSA_get0_pqg(key.dsa, NULL, &i, NULL);
3934 bn_dup_nil(L, i);
3935
3936 break;
3937 case PK_DSA_G:
3938 DSA_get0_pqg(key.dsa, NULL, NULL, &i);
3939 bn_dup_nil(L, i);
3940
3941 break;
3942 case PK_DSA_PUB_KEY:
3943 DSA_get0_key(key.dsa, &i, NULL);
3944 bn_dup_nil(L, i);
3945
3946 break;
3947 case PK_DSA_PRIV_KEY:
3948 DSA_get0_key(key.dsa, NULL, &i);
3949 bn_dup_nil(L, i);
3950
3951 break;
3952 case PK_DH_P:
3953 DH_get0_pqg(key.dh, &i, NULL, NULL);
3954 bn_dup_nil(L, i);
3955
3956 break;
3957 case PK_DH_G:
3958 DH_get0_pqg(key.dh, NULL, NULL, &i);
3959 bn_dup_nil(L, i);
3960
3961 break;
3962 case PK_DH_PUB_KEY:
3963 DH_get0_key(key.dh, &i, NULL);
3964 bn_dup_nil(L, i);
3965
3966 break;
3967 case PK_DH_PRIV_KEY:
3968 DH_get0_key(key.dh, NULL, &i);
3969 bn_dup_nil(L, i);
3970
3971 break;
3972#ifndef OPENSSL_NO_EC
3973 case PK_EC_GROUP:
3974 ecg_dup_nil(L, EC_KEY_get0_group(key.ec));
3975
3976 break;
3977 case PK_EC_PUB_KEY: {
3978 const EC_GROUP *group;
3979 const EC_POINT *pub_key;
3980
3981 if ((group = EC_KEY_get0_group(key.ec)) && (pub_key = EC_KEY_get0_public_key(key.ec))) {
3982 bn_dup_nil(L, EC_POINT_point2bn(group, pub_key, EC_KEY_get_conv_form(key.ec), NULL, getctx(L)));
3983 } else {
3984 lua_pushnil(L);
3985 }
3986
3987 break;
3988 }
3989 case PK_EC_PRIV_KEY:
3990 bn_dup_nil(L, EC_KEY_get0_private_key(key.ec));
3991
3992 break;
3993#endif
3994 default:
3995 luaL_error(L, "%d: invalid EVP_PKEY parameter", which);
3996 }
3997
3998 return;
3999} /* pk_pushparam() */
4000
4001
4002#define pk_setparam_bn_dup(L, index, dst) do { \
4003 BIGNUM *tmp = checkbig((L), (index)); \
4004 if (!(*dst = BN_dup(tmp))) \
4005 goto sslerr; \
4006} while (0)
4007
4008static void pk_setparam(lua_State *L, void *base_key, enum pk_param which, int index) {
4009 union {
4010 RSA *rsa;
4011 DH *dh;
4012 DSA *dsa;
4013#ifndef OPENSSL_NO_EC
4014 EC_KEY *ec;
4015#endif
4016 } key = { base_key };
4017 BIGNUM *i;
4018
4019 switch (which) {
4020 case PK_RSA_N:
4021 pk_setparam_bn_dup(L, index, &i);
4022 RSA_set0_key(key.rsa, i, NULL, NULL);
4023
4024 break;
4025 case PK_RSA_E:
4026 pk_setparam_bn_dup(L, index, &i);
4027 RSA_set0_key(key.rsa, NULL, i, NULL);
4028
4029 break;
4030 case PK_RSA_D:
4031 pk_setparam_bn_dup(L, index, &i);
4032 RSA_set0_key(key.rsa, NULL, NULL, i);
4033
4034 break;
4035 case PK_RSA_P:
4036 pk_setparam_bn_dup(L, index, &i);
4037 RSA_set0_factors(key.rsa, i, NULL);
4038
4039 break;
4040 case PK_RSA_Q:
4041 pk_setparam_bn_dup(L, index, &i);
4042 RSA_set0_factors(key.rsa, NULL, i);
4043
4044 break;
4045 case PK_RSA_DMP1:
4046 pk_setparam_bn_dup(L, index, &i);
4047 RSA_set0_crt_params(key.rsa, i, NULL, NULL);
4048
4049 break;
4050 case PK_RSA_DMQ1:
4051 pk_setparam_bn_dup(L, index, &i);
4052 RSA_set0_crt_params(key.rsa, NULL, i, NULL);
4053
4054 break;
4055 case PK_RSA_IQMP:
4056 pk_setparam_bn_dup(L, index, &i);
4057 RSA_set0_crt_params(key.rsa, NULL, NULL, i);
4058
4059 break;
4060 case PK_DSA_P:
4061 pk_setparam_bn_dup(L, index, &i);
4062 DSA_set0_pqg(key.dsa, i, NULL, NULL);
4063
4064 break;
4065 case PK_DSA_Q:
4066 pk_setparam_bn_dup(L, index, &i);
4067 DSA_set0_pqg(key.dsa, NULL, i, NULL);
4068
4069 break;
4070 case PK_DSA_G:
4071 pk_setparam_bn_dup(L, index, &i);
4072 DSA_set0_pqg(key.dsa, NULL, NULL, i);
4073
4074 break;
4075 case PK_DSA_PUB_KEY:
4076 pk_setparam_bn_dup(L, index, &i);
4077 DSA_set0_key(key.dsa, i, NULL);
4078
4079 break;
4080 case PK_DSA_PRIV_KEY:
4081 pk_setparam_bn_dup(L, index, &i);
4082 DSA_set0_key(key.dsa, NULL, i);
4083
4084 break;
4085 case PK_DH_P:
4086 pk_setparam_bn_dup(L, index, &i);
4087 DH_set0_pqg(key.dh, i, NULL, NULL);
4088
4089 break;
4090 case PK_DH_G:
4091 pk_setparam_bn_dup(L, index, &i);
4092 DH_set0_pqg(key.dh, NULL, NULL, i);
4093
4094 break;
4095 case PK_DH_PUB_KEY:
4096 pk_setparam_bn_dup(L, index, &i);
4097 DH_set0_key(key.dh, i, NULL);
4098
4099 break;
4100 case PK_DH_PRIV_KEY:
4101 pk_setparam_bn_dup(L, index, &i);
4102 DH_set0_key(key.dh, NULL, i);
4103
4104 break;
4105#ifndef OPENSSL_NO_EC
4106 case PK_EC_GROUP: {
4107 const EC_GROUP *group = checksimple(L, index, EC_GROUP_CLASS);
4108
4109 if (!EC_KEY_set_group(key.ec, group))
4110 goto sslerr;
4111
4112 break;
4113 }
4114 case PK_EC_PUB_KEY: {
4115 const BIGNUM *n = checkbig(L, index);
4116 const EC_GROUP *group;
4117 EC_POINT *pub_key;
4118 _Bool okay;
4119
4120 if (!(group = EC_KEY_get0_group(key.ec)))
4121 luaL_error(L, "unable to set EC pub_key (no group defined)");
4122
4123 if (!(pub_key = EC_POINT_bn2point(group, n, NULL, getctx(L))))
4124 goto sslerr;
4125
4126 /* NB: copies key, doesn't share or take ownership */
4127 okay = EC_KEY_set_public_key(key.ec, pub_key);
4128 EC_POINT_free(pub_key);
4129 if (!okay)
4130 goto sslerr;
4131
4132 break;
4133 }
4134 case PK_EC_PRIV_KEY: {
4135 const BIGNUM *n = checkbig(L, index);
4136
4137 /* NB: copies key, doesn't share or take ownership */
4138 if (!EC_KEY_set_private_key(key.ec, n))
4139 goto sslerr;
4140
4141 break;
4142 }
4143#endif
4144 default:
4145 luaL_error(L, "%d: invalid EVP_PKEY parameter", which);
4146 }
4147
4148 return;
4149sslerr:
4150 auxL_error(L, auxL_EOPENSSL, "pkey:setParameters");
4151
4152 return;
4153} /* pk_setparam() */
4154
4155
4156static int pk_getParameters(lua_State *L) {
4157 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
4158 int base_type = EVP_PKEY_base_id(key);
4159 void *base_key;
4160 const char *const *optlist;
4161 int nopts, optoffset, otop, index, tindex;
4162
4163 if (!(base_key = EVP_PKEY_get0(key)))
4164 goto sslerr;
4165
4166 if (!(optlist = pk_getoptlist(base_type, &nopts, &optoffset)))
4167 return luaL_error(L, "%d: unsupported EVP_PKEY base type", base_type);
4168
4169 if (lua_isnoneornil(L, 2)) {
4170 const char *const *optname;
4171
4172 /*
4173 * Use special "{" parameter to tell loop to push table.
4174 * Subsequent parameters will be assigned as fields.
4175 */
4176 lua_pushstring(L, "{");
4177 luaL_checkstack(L, nopts, "too many arguments");
4178 for (optname = optlist; *optname; optname++) {
4179 lua_pushstring(L, *optname);
4180 }
4181 }
4182
4183 otop = lua_gettop(L);
4184
4185 /* provide space for results and working area */
4186 luaL_checkstack(L, (otop - 1) + LUA_MINSTACK, "too many arguments");
4187
4188 /* no table index, yet */
4189 tindex = 0;
4190
4191 for (index = 2; index <= otop; index++) {
4192 const char *optname = luaL_checkstring(L, index);
4193 int optid;
4194
4195 if (*optname == '{') {
4196 lua_newtable(L);
4197 tindex = lua_gettop(L);
4198 } else {
4199 optid = luaL_checkoption(L, index, NULL, optlist) + optoffset;
4200 pk_pushparam(L, base_key, optid);
4201
4202 if (tindex) {
4203 lua_setfield(L, tindex, optname);
4204 }
4205 }
4206 }
4207
4208 return lua_gettop(L) - otop;
4209sslerr:
4210 return auxL_error(L, auxL_EOPENSSL, "pkey:getParameters");
4211} /* pk_getParameters() */
4212
4213
4214static int pk_setParameters(lua_State *L) {
4215 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
4216 int base_type = EVP_PKEY_base_id(key);
4217 void *base_key;
4218 const char *const *optlist;
4219 int optindex, optoffset;
4220
4221 luaL_checktype(L, 2, LUA_TTABLE);
4222
4223 if (!(base_key = EVP_PKEY_get0(key)))
4224 goto sslerr;
4225
4226 if (!(optlist = pk_getoptlist(base_type, NULL, &optoffset)))
4227 return luaL_error(L, "%d: unsupported EVP_PKEY base type", base_type);
4228
4229 for (optindex = 0; optlist[optindex]; optindex++) {
4230 if (getfield(L, 2, optlist[optindex])) {
4231 pk_setparam(L, base_key, optindex + optoffset, -1);
4232 lua_pop(L, 1);
4233 }
4234 }
4235
4236 return 0;
4237sslerr:
4238 return auxL_error(L, auxL_EOPENSSL, "pkey:setParameters");
4239} /* pk_setParameters() */
4240
4241
4242static int pk__tostring(lua_State *L) {
4243 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
4244 int type = optencoding(L, 2, "pem", X509_PEM|X509_DER);
4245 BIO *bio = getbio(L);
4246 char *data;
4247 long len;
4248
4249 switch (type) {
4250 case X509_PEM:
4251 if (!PEM_write_bio_PUBKEY(bio, key))
4252 return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring");
4253 break;
4254 case X509_DER:
4255 if (!i2d_PUBKEY_bio(bio, key))
4256 return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring");
4257 break;
4258 } /* switch() */
4259
4260 len = BIO_get_mem_data(bio, &data);
4261
4262 lua_pushlstring(L, data, len);
4263
4264 return 1;
4265} /* pk__tostring() */
4266
4267
4268static int pk__index(lua_State *L) {
4269 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
4270 void *base_key;
4271 const char *const *optlist;
4272 int optoffset, listoffset;
4273
4274 lua_pushvalue(L, lua_upvalueindex(1));
4275 lua_pushvalue(L, 2);
4276 lua_gettable(L, -2);
4277
4278 if (!lua_isnil(L, -1))
4279 return 1;
4280
4281 if (!lua_isstring(L, 2))
4282 return 0;
4283 if (!(base_key = EVP_PKEY_get0(key)))
4284 return 0;
4285 if (!(optlist = pk_getoptlist(EVP_PKEY_base_id(key), NULL, &optoffset)))
4286 return 0;
4287 if (-1 == (listoffset = auxL_testoption(L, 2, NULL, optlist, 0)))
4288 return 0;
4289
4290 pk_pushparam(L, base_key, listoffset + optoffset);
4291
4292 return 1;
4293} /* pk__index() */
4294
4295
4296static int pk__newindex(lua_State *L) {
4297 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
4298 void *base_key;
4299 const char *const *optlist;
4300 int optoffset, listoffset;
4301
4302 if (!lua_isstring(L, 2))
4303 return 0;
4304 if (!(base_key = EVP_PKEY_get0(key)))
4305 return 0;
4306 if (!(optlist = pk_getoptlist(EVP_PKEY_base_id(key), NULL, &optoffset)))
4307 return 0;
4308 if (-1 == (listoffset = auxL_testoption(L, 2, NULL, optlist, 0)))
4309 return 0;
4310
4311 pk_setparam(L, base_key, listoffset + optoffset, 3);
4312
4313 return 0;
4314} /* pk__newindex() */
4315
4316
4317static int pk__gc(lua_State *L) {
4318 EVP_PKEY **ud = luaL_checkudata(L, 1, PKEY_CLASS);
4319
4320 if (*ud) {
4321 EVP_PKEY_free(*ud);
4322 *ud = NULL;
4323 }
4324
4325 return 0;
4326} /* pk__gc() */
4327
4328
4329static const auxL_Reg pk_methods[] = {
4330 { "type", &pk_type },
4331 { "setPublicKey", &pk_setPublicKey },
4332 { "setPrivateKey", &pk_setPrivateKey },
4333#if HAVE_EVP_PKEY_CTX_NEW
4334 { "decrypt", &pk_decrypt },
4335 { "encrypt", &pk_encrypt },
4336#endif
4337 { "sign", &pk_sign },
4338 { "verify", &pk_verify },
4339 { "getDefaultDigestName", &pk_getDefaultDigestName },
4340 { "toPEM", &pk_toPEM },
4341 { "getParameters", &pk_getParameters },
4342 { "setParameters", &pk_setParameters },
4343 { NULL, NULL },
4344};
4345
4346static const auxL_Reg pk_metatable[] = {
4347 { "__tostring", &pk__tostring },
4348 { "__index", &pk__index, 1 },
4349 { "__newindex", &pk__newindex, 1 },
4350 { "__gc", &pk__gc },
4351 { NULL, NULL },
4352};
4353
4354
4355static const auxL_Reg pk_globals[] = {
4356 { "new", &pk_new },
4357 { "interpose", &pk_interpose },
4358 { NULL, NULL },
4359};
4360
4361static void pk_luainit(lua_State *L, _Bool reset) {
4362 char **k;
4363 if (!auxL_newmetatable(L, PKEY_CLASS, reset))
4364 return;
4365 auxL_setfuncs(L, pk_metatable, 0);
4366 auxL_newlib(L, pk_methods, 0);
4367 for (k = (char *[]){ "__index", "__newindex", 0 }; *k; k++) {
4368 lua_getfield(L, -2, *k); /* closure */
4369 lua_pushvalue(L, -2); /* method table */
4370 lua_setupvalue(L, -2, 1);
4371 }
4372 lua_pop(L, 2);
4373} /* pk_luainit() */
4374
4375static const auxL_IntegerReg pk_rsa_pad_opts[] = {
4376 { "RSA_PKCS1_PADDING", RSA_PKCS1_PADDING }, // PKCS#1 padding
4377 { "RSA_SSLV23_PADDING", RSA_SSLV23_PADDING }, // SSLv23 padding
4378 { "RSA_NO_PADDING", RSA_NO_PADDING }, // no padding
4379 { "RSA_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING }, // OAEP padding (encrypt and decrypt only)
4380 { "RSA_X931_PADDING", RSA_X931_PADDING }, // (signature operations only)
4381#if HAVE_RSA_PKCS1_PSS_PADDING
4382 { "RSA_PKCS1_PSS_PADDING", RSA_PKCS1_PSS_PADDING }, // (sign and verify only)
4383#endif
4384 { NULL, 0 },
4385};
4386
4387int luaopen__openssl_pkey(lua_State *L) {
4388 initall(L);
4389
4390 auxL_newlib(L, pk_globals, 0);
4391 auxL_setintegers(L, pk_rsa_pad_opts);
4392
4393 return 1;
4394} /* luaopen__openssl_pkey() */
4395
4396
4397/*
4398 * Deprecated module name.
4399 */
4400int luaopen__openssl_pubkey(lua_State *L) {
4401 return luaopen__openssl_pkey(L);
4402} /* luaopen__openssl_pubkey() */
4403
4404
4405/*
4406 * EC_GROUP - openssl.ec.group
4407 *
4408 * NOTE: Ensure copy-by-value semantics when passing EC_GROUP objects as it
4409 * doesn't support reference counting. The only persistent reference should
4410 * be the Lua userdata value.
4411 *
4412 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
4413
4414#ifndef OPENSSL_NO_EC
4415
4416static EC_GROUP *ecg_dup(lua_State *L, const EC_GROUP *src) {
4417 EC_GROUP **ud = prepsimple(L, EC_GROUP_CLASS);
4418
4419 if (!(*ud = EC_GROUP_dup(src)))
4420 auxL_error(L, auxL_EOPENSSL, "group");
4421
4422 return *ud;
4423} /* ecg_dup() */
4424
4425static EC_GROUP *ecg_dup_nil(lua_State *L, const EC_GROUP *src) {
4426 return (src)? ecg_dup(L, src) : (lua_pushnil(L), (EC_GROUP *)0);
4427} /* ecg_dup_nil() */
4428
4429static EC_GROUP *ecg_push_by_nid(lua_State *L, int nid) {
4430 EC_GROUP **group = prepsimple(L, EC_GROUP_CLASS);
4431
4432 if (!(*group = EC_GROUP_new_by_curve_name(nid)))
4433 goto oops;
4434
4435 EC_GROUP_set_asn1_flag(*group, OPENSSL_EC_NAMED_CURVE);
4436
4437 /* compressed points may be patented */
4438 EC_GROUP_set_point_conversion_form(*group, POINT_CONVERSION_UNCOMPRESSED);
4439
4440 return *group;
4441oops:
4442 lua_pop(L, 1);
4443
4444 return NULL;
4445} /* ecg_push_by_nid() */
4446
4447static int ecg_new(lua_State *L) {
4448 switch (lua_type(L, 1)) {
4449 case LUA_TSTRING: {
4450 const char *data;
4451 size_t datalen;
4452 int nid, type, goterr;
4453 BIO *bio;
4454 EC_GROUP **group;
4455
4456 data = luaL_checklstring(L, 1, &datalen);
4457
4458 if (auxS_txt2nid(&nid, data)) {
4459 if (!ecg_push_by_nid(L, nid))
4460 goto sslerr;
4461 } else {
4462 type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER);
4463 group = prepsimple(L, EC_GROUP_CLASS);
4464
4465 luaL_argcheck(L, datalen < INT_MAX, 1, "string too long");
4466 if (!(bio = BIO_new_mem_buf((void *)data, datalen)))
4467 return auxL_error(L, auxL_EOPENSSL, "group.new");
4468
4469 goterr = 0;
4470
4471 if (type == X509_PEM || type == X509_ANY) {
4472 goterr |= !(*group = PEM_read_bio_ECPKParameters(bio, NULL, 0, ""));
4473 }
4474
4475 if (!*group && (type == X509_DER || type == X509_ANY)) {
4476 BIO_reset(bio);
4477 goterr |= !(*group = d2i_ECPKParameters_bio(bio, NULL));
4478 }
4479
4480 BIO_free(bio);
4481
4482 if (!*group)
4483 return auxL_error(L, auxL_EOPENSSL, "group.new");
4484 if (goterr)
4485 ERR_clear_error();
4486 }
4487
4488 return 1;
4489 }
4490 case LUA_TNUMBER: {
4491 int nid = luaL_checkinteger(L, 2);
4492
4493 if (!ecg_push_by_nid(L, nid))
4494 goto sslerr;
4495
4496 return 1;
4497 }
4498 default:
4499 return luaL_error(L, "%s: unknown group initializer", lua_typename(L, lua_type(L, 1)));
4500 } /* switch() */
4501
4502 return 0;
4503sslerr:
4504 return auxL_error(L, auxL_EOPENSSL, "group.new");
4505} /* ecg_new() */
4506
4507static int ecg_interpose(lua_State *L) {
4508 return interpose(L, EC_GROUP_CLASS);
4509} /* ecg_interpose() */
4510
4511static int ecg_tostring(lua_State *L) {
4512 EC_GROUP *group = checksimple(L, 1, EC_GROUP_CLASS);
4513 int how = optencoding(L, 2, "pem", X509_PEM|X509_DER|X509_TXT);
4514 BIO *bio = getbio(L);
4515 char *bytes;
4516 int len, indent;
4517
4518 switch (how) {
4519 case X509_PEM:
4520 if (!PEM_write_bio_ECPKParameters(bio, group))
4521 goto sslerr;
4522 break;
4523 case X509_DER:
4524 if (!i2d_ECPKParameters_bio(bio, group))
4525 goto sslerr;
4526 break;
4527 case X509_TXT:
4528 indent = auxL_optinteger(L, 3, 0, 0, INT_MAX);
4529 if (!ECPKParameters_print(bio, group, indent))
4530 goto sslerr;
4531 break;
4532 }
4533
4534 len = BIO_get_mem_data(bio, &bytes);
4535 lua_pushlstring(L, bytes, len);
4536
4537 return 1;
4538sslerr:
4539 return auxL_error(L, auxL_EOPENSSL, "group:__tostring");
4540} /* ecg_tostring() */
4541
4542static int ecg__tostring(lua_State *L) {
4543 return ecg_tostring(L);
4544} /* ecg__tostring() */
4545
4546static int ecg__gc(lua_State *L) {
4547 EC_GROUP **ud = luaL_checkudata(L, 1, EC_GROUP_CLASS);
4548
4549 if (*ud) {
4550 EC_GROUP_clear_free(*ud);
4551 *ud = NULL;
4552 }
4553
4554 return 0;
4555} /* ecg__gc() */
4556
4557static const auxL_Reg ecg_methods[] = {
4558 { "tostring", &ecg_tostring },
4559 { NULL, NULL },
4560};
4561
4562static const auxL_Reg ecg_metatable[] = {
4563 { "__tostring", &ecg__tostring },
4564 { "__gc", &ecg__gc },
4565 { NULL, NULL },
4566};
4567
4568static const auxL_Reg ecg_globals[] = {
4569 { "new", &ecg_new },
4570 { "interpose", &ecg_interpose },
4571 { NULL, NULL },
4572};
4573
4574#endif /* OPENSSL_NO_EC */
4575
4576int luaopen__openssl_ec_group(lua_State *L) {
4577#ifndef OPENSSL_NO_EC
4578 initall(L);
4579
4580 auxL_newlib(L, ecg_globals, 0);
4581
4582 return 1;
4583#else
4584 return 0;
4585#endif
4586} /* luaopen__openssl_ec_group() */
4587
4588
4589/*
4590 * X509_NAME - openssl.x509.name
4591 *
4592 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
4593
4594static X509_NAME *xn_dup(lua_State *L, X509_NAME *name) {
4595 X509_NAME **ud = prepsimple(L, X509_NAME_CLASS);
4596
4597 if (!(*ud = X509_NAME_dup(name)))
4598 auxL_error(L, auxL_EOPENSSL, "x509.name.dup");
4599
4600 return *ud;
4601} /* xn_dup() */
4602
4603
4604static int xn_new(lua_State *L) {
4605 X509_NAME **ud = prepsimple(L, X509_NAME_CLASS);
4606
4607 if (!(*ud = X509_NAME_new()))
4608 return auxL_error(L, auxL_EOPENSSL, "x509.name.new");
4609
4610 return 1;
4611} /* xn_new() */
4612
4613
4614static int xn_interpose(lua_State *L) {
4615 return interpose(L, X509_NAME_CLASS);
4616} /* xn_interpose() */
4617
4618
4619static int xn_add(lua_State *L) {
4620 X509_NAME *name = checksimple(L, 1, X509_NAME_CLASS);
4621 const char *nid = luaL_checkstring(L, 2);
4622 size_t len;
4623 const char *txt = luaL_checklstring(L, 3, &len);
4624 ASN1_OBJECT *obj;
4625 int ok;
4626
4627 if (!(obj = OBJ_txt2obj(nid, 0)))
4628 return luaL_error(L, "x509.name:add: %s: invalid NID", nid);
4629
4630 ok = !!X509_NAME_add_entry_by_OBJ(name, obj, MBSTRING_ASC, (unsigned char *)txt, len, -1, 0);
4631
4632 ASN1_OBJECT_free(obj);
4633
4634 if (!ok)
4635 return auxL_error(L, auxL_EOPENSSL, "x509.name:add");
4636
4637 lua_pushvalue(L, 1);
4638
4639 return 1;
4640} /* xn_add() */
4641
4642
4643static int xn_all(lua_State *L) {
4644 X509_NAME *name = checksimple(L, 1, X509_NAME_CLASS);
4645 int count = X509_NAME_entry_count(name);
4646 X509_NAME_ENTRY *entry;
4647 ASN1_OBJECT *obj;
4648 const char *id;
4649 char txt[256];
4650 int i, nid, len;
4651
4652 lua_newtable(L);
4653
4654 for (i = 0; i < count; i++) {
4655 if (!(entry = X509_NAME_get_entry(name, i)))
4656 continue;
4657
4658 lua_newtable(L);
4659
4660 obj = X509_NAME_ENTRY_get_object(entry);
4661 nid = OBJ_obj2nid(obj);
4662
4663 if (0 > (len = OBJ_obj2txt(txt, sizeof txt, obj, 1)))
4664 return auxL_error(L, auxL_EOPENSSL, "x509.name:all");
4665
4666 lua_pushlstring(L, txt, len);
4667
4668 if (nid != NID_undef && ((id = OBJ_nid2ln(nid)) || (id = OBJ_nid2sn(nid))))
4669 lua_pushstring(L, id);
4670 else
4671 lua_pushvalue(L, -1);
4672
4673 if (nid != NID_undef && (id = OBJ_nid2sn(nid)))
4674 lua_pushstring(L, id);
4675 else
4676 lua_pushvalue(L, -1);
4677
4678 lua_setfield(L, -4, "sn");
4679 lua_setfield(L, -3, "ln");
4680 lua_setfield(L, -2, "id");
4681
4682 len = ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry));
4683 lua_pushlstring(L, (char *)ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(entry)), len);
4684
4685 lua_setfield(L, -2, "blob");
4686
4687 lua_rawseti(L, -2, i + 1);
4688 }
4689
4690 return 1;
4691} /* xn_all() */
4692
4693
4694static int xn__next(lua_State *L) {
4695 X509_NAME *name = checksimple(L, lua_upvalueindex(1), X509_NAME_CLASS);
4696 X509_NAME_ENTRY *entry;
4697 ASN1_OBJECT *obj;
4698 char txt[256];
4699 int i, n, len;
4700
4701 lua_settop(L, 0);
4702
4703 i = lua_tointeger(L, lua_upvalueindex(2));
4704 n = X509_NAME_entry_count(name);
4705
4706 while (i < n) {
4707 if (!(entry = X509_NAME_get_entry(name, i++)))
4708 continue;
4709
4710 obj = X509_NAME_ENTRY_get_object(entry);
4711
4712 if (!(len = auxS_obj2txt(txt, sizeof txt, obj)))
4713 return auxL_error(L, auxL_EOPENSSL, "x509.name:__pairs");
4714 lua_pushlstring(L, txt, len);
4715
4716 len = ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry));
4717 lua_pushlstring(L, (char *)ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(entry)), len);
4718
4719 break;
4720 }
4721
4722 lua_pushinteger(L, i);
4723 lua_replace(L, lua_upvalueindex(2));
4724
4725 return lua_gettop(L);
4726} /* xn__next() */
4727
4728static int xn__pairs(lua_State *L) {
4729 lua_settop(L, 1);
4730 lua_pushinteger(L, 0);
4731
4732 lua_pushcclosure(L, &xn__next, 2);
4733
4734 return 1;
4735} /* xn__pairs() */
4736
4737
4738static int xn__gc(lua_State *L) {
4739 X509_NAME **ud = luaL_checkudata(L, 1, X509_NAME_CLASS);
4740
4741 if (*ud) {
4742 X509_NAME_free(*ud);
4743 *ud = NULL;
4744 }
4745
4746 return 0;
4747} /* xn__gc() */
4748
4749
4750static int xn__tostring(lua_State *L) {
4751 X509_NAME *name = checksimple(L, 1, X509_NAME_CLASS);
4752 char txt[1024] = { 0 };
4753
4754 /* FIXME: oneline is deprecated */
4755 X509_NAME_oneline(name, txt, sizeof txt);
4756
4757 lua_pushstring(L, txt);
4758
4759 return 1;
4760} /* xn__tostring() */
4761
4762
4763static const auxL_Reg xn_methods[] = {
4764 { "add", &xn_add },
4765 { "all", &xn_all },
4766 { NULL, NULL },
4767};
4768
4769static const auxL_Reg xn_metatable[] = {
4770 { "__pairs", &xn__pairs },
4771 { "__gc", &xn__gc },
4772 { "__tostring", &xn__tostring },
4773 { NULL, NULL },
4774};
4775
4776
4777static const auxL_Reg xn_globals[] = {
4778 { "new", &xn_new },
4779 { "interpose", &xn_interpose },
4780 { NULL, NULL },
4781};
4782
4783int luaopen__openssl_x509_name(lua_State *L) {
4784 initall(L);
4785
4786 auxL_newlib(L, xn_globals, 0);
4787
4788 return 1;
4789} /* luaopen__openssl_x509_name() */
4790
4791
4792/*
4793 * GENERAL_NAMES - openssl.x509.altname
4794 *
4795 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
4796
4797static GENERAL_NAMES *gn_dup(lua_State *L, GENERAL_NAMES *gens) {
4798 GENERAL_NAMES **ud = prepsimple(L, X509_GENS_CLASS);
4799
4800 if (!(*ud = sk_GENERAL_NAME_dup(gens)))
4801 auxL_error(L, auxL_EOPENSSL, "x509.altname.dup");
4802
4803 return *ud;
4804} /* gn_dup() */
4805
4806
4807static int gn_new(lua_State *L) {
4808 GENERAL_NAMES **ud = prepsimple(L, X509_GENS_CLASS);
4809
4810 if (!(*ud = sk_GENERAL_NAME_new_null()))
4811 return auxL_error(L, auxL_EOPENSSL, "x509.altname.new");
4812
4813 return 1;
4814} /* gn_new() */
4815
4816
4817static int gn_interpose(lua_State *L) {
4818 return interpose(L, X509_GENS_CLASS);
4819} /* gn_interpose() */
4820
4821
4822static int gn_checktype(lua_State *L, int index) {
4823 static const struct { int type; const char *name; } table[] = {
4824 { GEN_EMAIL, "RFC822Name" },
4825 { GEN_EMAIL, "RFC822" },
4826 { GEN_EMAIL, "email" },
4827 { GEN_URI, "UniformResourceIdentifier" },
4828 { GEN_URI, "URI" },
4829 { GEN_DNS, "DNSName" },
4830 { GEN_DNS, "DNS" },
4831 { GEN_IPADD, "IPAddress" },
4832 { GEN_IPADD, "IP" },
4833 { GEN_DIRNAME, "DirName" },
4834 };
4835 const char *type = luaL_checkstring(L, index);
4836 unsigned i;
4837
4838 for (i = 0; i < countof(table); i++) {
4839 if (strieq(table[i].name, type))
4840 return table[i].type;
4841 }
4842
4843 return luaL_error(L, "%s: invalid type", type), 0;
4844} /* gn_checktype() */
4845
4846
4847static int gn_add(lua_State *L) {
4848 GENERAL_NAMES *gens = checksimple(L, 1, X509_GENS_CLASS);
4849 int type = gn_checktype(L, 2);
4850 X509_NAME *name;
4851 size_t len;
4852 const char *txt;
4853 GENERAL_NAME *gen = NULL;
4854 union { struct in6_addr in6; struct in_addr in; } ip;
4855
4856 switch (type) {
4857 case GEN_DIRNAME:
4858 name = checksimple(L, 3, X509_NAME_CLASS);
4859
4860 if (!(gen = GENERAL_NAME_new()))
4861 goto error;
4862
4863 gen->type = type;
4864
4865 if (!(gen->d.dirn = X509_NAME_dup(name)))
4866 goto error;
4867
4868 break;
4869 case GEN_IPADD:
4870 txt = luaL_checkstring(L, 3);
4871
4872 if (strchr(txt, ':')) {
4873 if (1 != inet_pton(AF_INET6, txt, &ip.in6))
4874 return luaL_error(L, "%s: invalid address", txt);
4875
4876 txt = (char *)ip.in6.s6_addr;
4877 len = 16;
4878 } else {
4879 if (1 != inet_pton(AF_INET, txt, &ip.in))
4880 return luaL_error(L, "%s: invalid address", txt);
4881
4882 txt = (char *)&ip.in.s_addr;
4883 len = 4;
4884 }
4885
4886 goto text;
4887 default:
4888 txt = luaL_checklstring(L, 3, &len);
4889text:
4890 if (!(gen = GENERAL_NAME_new()))
4891 goto error;
4892
4893 gen->type = type;
4894
4895 if (!(gen->d.ia5 = ASN1_STRING_type_new(V_ASN1_IA5STRING)))
4896 goto error;
4897
4898 if (!ASN1_STRING_set(gen->d.ia5, (unsigned char *)txt, len))
4899 goto error;
4900 break;
4901 } /* switch() */
4902
4903 sk_GENERAL_NAME_push(gens, gen);
4904
4905 lua_pushvalue(L, 1);
4906
4907 return 1;
4908error:
4909 GENERAL_NAME_free(gen);
4910
4911 return auxL_error(L, auxL_EOPENSSL, "x509.altname:add");
4912} /* gn_add() */
4913
4914
4915#define GN_PUSHSTRING(L, o) \
4916 lua_pushlstring((L), (char *)ASN1_STRING_get0_data((o)), ASN1_STRING_length((o)))
4917
4918static int gn__next(lua_State *L) {
4919 GENERAL_NAMES *gens = checksimple(L, lua_upvalueindex(1), X509_GENS_CLASS);
4920 int i = lua_tointeger(L, lua_upvalueindex(2));
4921 int n = sk_GENERAL_NAME_num(gens);
4922
4923 lua_settop(L, 0);
4924
4925 while (i < n) {
4926 GENERAL_NAME *name;
4927 const char *txt;
4928 size_t len;
4929 union { struct in_addr in; struct in6_addr in6; } ip;
4930 char buf[INET6_ADDRSTRLEN + 1];
4931 int af;
4932
4933 if (!(name = sk_GENERAL_NAME_value(gens, i++)))
4934 continue;
4935
4936 switch (name->type) {
4937 case GEN_EMAIL:
4938 lua_pushstring(L, "email");
4939 GN_PUSHSTRING(L, name->d.rfc822Name);
4940
4941 break;
4942 case GEN_URI:
4943 lua_pushstring(L, "URI");
4944 GN_PUSHSTRING(L, name->d.uniformResourceIdentifier);
4945
4946 break;
4947 case GEN_DNS:
4948 lua_pushstring(L, "DNS");
4949 GN_PUSHSTRING(L, name->d.dNSName);
4950
4951 break;
4952 case GEN_IPADD:
4953 txt = (char *)ASN1_STRING_get0_data(name->d.iPAddress);
4954 len = ASN1_STRING_length(name->d.iPAddress);
4955
4956 switch (len) {
4957 case 16:
4958 memcpy(ip.in6.s6_addr, txt, 16);
4959 af = AF_INET6;
4960
4961 break;
4962 case 4:
4963 memcpy(&ip.in.s_addr, txt, 4);
4964 af = AF_INET;
4965
4966 break;
4967 default:
4968 continue;
4969 }
4970
4971 if (!(txt = inet_ntop(af, &ip, buf, sizeof buf)))
4972 continue;
4973
4974 len = strlen(txt);
4975
4976 lua_pushstring(L, "IP");
4977 lua_pushlstring(L, txt, len);
4978
4979 break;
4980 case GEN_DIRNAME:
4981 lua_pushstring(L, "DirName");
4982 xn_dup(L, name->d.dirn);
4983
4984 break;
4985 default:
4986 continue;
4987 } /* switch() */
4988
4989 break;
4990 } /* while() */
4991
4992 lua_pushinteger(L, i);
4993 lua_replace(L, lua_upvalueindex(2));
4994
4995 return lua_gettop(L);
4996} /* gn__next() */
4997
4998static int gn__pairs(lua_State *L) {
4999 lua_settop(L, 1);
5000 lua_pushinteger(L, 0);
5001 lua_pushcclosure(L, &gn__next, 2);
5002
5003 return 1;
5004} /* gn__pairs() */
5005
5006
5007static int gn__gc(lua_State *L) {
5008 GENERAL_NAMES **ud = luaL_checkudata(L, 1, X509_GENS_CLASS);
5009
5010 if (*ud) {
5011 sk_GENERAL_NAME_pop_free(*ud, GENERAL_NAME_free);
5012 *ud = NULL;
5013 }
5014
5015 return 0;
5016} /* gn__gc() */
5017
5018
5019static const auxL_Reg gn_methods[] = {
5020 { "add", &gn_add },
5021 { NULL, NULL },
5022};
5023
5024static const auxL_Reg gn_metatable[] = {
5025 { "__pairs", &gn__pairs },
5026 { "__gc", &gn__gc },
5027 { NULL, NULL },
5028};
5029
5030
5031static const auxL_Reg gn_globals[] = {
5032 { "new", &gn_new },
5033 { "interpose", &gn_interpose },
5034 { NULL, NULL },
5035};
5036
5037int luaopen__openssl_x509_altname(lua_State *L) {
5038 initall(L);
5039
5040 auxL_newlib(L, gn_globals, 0);
5041
5042 return 1;
5043} /* luaopen__openssl_x509_altname() */
5044
5045
5046/*
5047 * X509_EXTENSION - openssl.x509.extension
5048 *
5049 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5050
5051static _Bool xe_new_isder(const char *value, _Bool *crit) {
5052 if (!strcmp(value, "critical,DER"))
5053 return (*crit = 1), 1;
5054 if (!strcmp(value, "DER"))
5055 return (*crit = 0), 1;
5056
5057 return 0;
5058} /* xs_new_isder() */
5059
5060static CONF* loadconf(lua_State *L, int idx) {
5061 CONF *conf;
5062 size_t len;
5063 const char *cdata = luaL_checklstring(L, idx, &len);
5064 BIO *bio = getbio(L);
5065 if (BIO_write(bio, cdata, len) < 0)
5066 return NULL;
5067
5068 if (!(conf = NCONF_new(NULL)))
5069 return NULL;
5070
5071 if (!NCONF_load_bio(conf, bio, NULL)) {
5072 NCONF_free(conf);
5073 return NULL;
5074 }
5075
5076 return conf;
5077}
5078
5079static int xe_new(lua_State *L) {
5080 const char *name = luaL_checkstring(L, 1);
5081 const char *value = luaL_checkstring(L, 2);
5082 ASN1_OBJECT *obj = NULL;
5083 ASN1_STRING *oct = NULL;
5084 CONF *conf = NULL;
5085 X509V3_CTX cbuf = { 0 }, *ctx = NULL;
5086 X509_EXTENSION **ud;
5087 _Bool crit;
5088
5089 lua_settop(L, 3);
5090 ud = prepsimple(L, X509_EXT_CLASS);
5091
5092 if (xe_new_isder(value, &crit)) {
5093 size_t len;
5094 const char *cdata = lua_tolstring(L, 3, &len);
5095 if (!(obj = OBJ_txt2obj(name, 0)))
5096 goto error;
5097 if (!(oct = ASN1_STRING_new()))
5098 goto error;
5099 if (!ASN1_STRING_set(oct, cdata, len))
5100 goto error;
5101 if (!(*ud = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct)))
5102 goto error;
5103
5104 ASN1_OBJECT_free(obj);
5105 ASN1_STRING_free(oct);
5106
5107 return 1;
5108 }
5109
5110 switch (lua_type(L, 3)) {
5111 case LUA_TNONE:
5112 case LUA_TNIL:
5113 break;
5114 case LUA_TSTRING: {
5115 if (!(conf = loadconf(L, 3)))
5116 goto error;
5117
5118 ctx = &cbuf;
5119 X509V3_set_nconf(ctx, conf);
5120 break;
5121 }
5122 case LUA_TTABLE: {
5123 X509 *issuer = NULL;
5124 X509 *subject = NULL;
5125 X509_REQ *request = NULL;
5126 X509_CRL *crl = NULL;
5127 int flags = 0;
5128
5129 ctx = &cbuf;
5130
5131 if (lua_getfield(L, 3, "db") != LUA_TNIL) {
5132 if (!(conf = loadconf(L, -1)))
5133 goto error;
5134 X509V3_set_nconf(ctx, conf);
5135 }
5136 lua_pop(L, 1);
5137
5138 if (lua_getfield(L, 3, "issuer") != LUA_TNIL) {
5139 issuer = checksimple(L, -1, X509_CERT_CLASS);
5140 }
5141 lua_pop(L, 1);
5142
5143 if (lua_getfield(L, 3, "subject") != LUA_TNIL) {
5144 subject = checksimple(L, -1, X509_CERT_CLASS);
5145 }
5146 lua_pop(L, 1);
5147
5148 if (lua_getfield(L, 3, "request") != LUA_TNIL) {
5149 request = checksimple(L, -1, X509_CSR_CLASS);
5150 }
5151 lua_pop(L, 1);
5152
5153 if (lua_getfield(L, 3, "crl") != LUA_TNIL) {
5154 crl = checksimple(L, -1, X509_CRL_CLASS);
5155 }
5156 lua_pop(L, 1);
5157
5158 if (lua_getfield(L, 3, "flags") != LUA_TNIL) {
5159 flags = luaL_checkinteger(L, -1);
5160 }
5161 lua_pop(L, 1);
5162
5163 X509V3_set_ctx(ctx, issuer, subject, request, crl, flags);
5164 break;
5165 }
5166 default:
5167 return luaL_argerror(L, 3, "invalid extra parameter (expected string, table or nil)");
5168 }
5169
5170 /*
5171 * NOTE: AFAICT neither name nor value are modified. The API just
5172 * doesn't have the proper const-qualifiers. See
5173 * crypto/x509v3/v3_conf.c in OpenSSL.
5174 *
5175 * Also seems to be okay to pass NULL conf. Both NCONF_get_section
5176 * and sk_CONF_VALUE_num can handle NULL arguments. See do_ext_nconf
5177 * in v3_conf.c.
5178 */
5179 if (!(*ud = X509V3_EXT_nconf(conf, ctx, (char *)name, (char *)value)))
5180 goto error;
5181
5182 if (conf)
5183 NCONF_free(conf);
5184
5185 return 1;
5186error:
5187 if (obj)
5188 ASN1_OBJECT_free(obj);
5189 if (oct)
5190 ASN1_STRING_free(oct);
5191 if (conf)
5192 NCONF_free(conf);
5193
5194 return auxL_error(L, auxL_EOPENSSL, "x509.extension.new");
5195} /* xe_new() */
5196
5197
5198static int xe_interpose(lua_State *L) {
5199 return interpose(L, X509_EXT_CLASS);
5200} /* xe_interpose() */
5201
5202
5203static int xe_getID(lua_State *L) {
5204 X509_EXTENSION *ext = checksimple(L, 1, X509_EXT_CLASS);
5205 ASN1_OBJECT *obj = X509_EXTENSION_get0_object(ext);
5206 char txt[256];
5207 int len;
5208
5209 if (!(len = auxS_obj2id(txt, sizeof txt, obj)))
5210 return auxL_error(L, auxL_EOPENSSL, "x509.extension:getID");
5211
5212 lua_pushlstring(L, txt, len);
5213
5214 return 1;
5215} /* xe_getID() */
5216
5217
5218static int xe_getName(lua_State *L) {
5219 X509_EXTENSION *ext = checksimple(L, 1, X509_EXT_CLASS);
5220 char txt[256];
5221 int len;
5222
5223 if (!(len = auxS_obj2txt(txt, sizeof txt, X509_EXTENSION_get0_object(ext))))
5224 return auxL_error(L, auxL_EOPENSSL, "x509.extension:getName");
5225
5226 lua_pushlstring(L, txt, len);
5227
5228 return 1;
5229} /* xe_getName() */
5230
5231
5232static int xe_getShortName(lua_State *L) {
5233 X509_EXTENSION *ext = checksimple(L, 1, X509_EXT_CLASS);
5234 char txt[256];
5235 int len;
5236
5237 if (!(len = auxS_obj2sn(txt, sizeof txt, X509_EXTENSION_get0_object(ext))))
5238 return 0;
5239
5240 lua_pushlstring(L, txt, len);
5241
5242 return 1;
5243} /* xe_getShortName() */
5244
5245
5246static int xe_getLongName(lua_State *L) {
5247 X509_EXTENSION *ext = checksimple(L, 1, X509_EXT_CLASS);
5248 char txt[256];
5249 int len;
5250
5251 if (!(len = auxS_obj2ln(txt, sizeof txt, X509_EXTENSION_get0_object(ext))))
5252 return 0;
5253
5254 lua_pushlstring(L, txt, len);
5255
5256 return 1;
5257} /* xe_getLongName() */
5258
5259
5260static int xe_getData(lua_State *L) {
5261 ASN1_STRING *data = X509_EXTENSION_get0_data(checksimple(L, 1, X509_EXT_CLASS));
5262
5263 lua_pushlstring(L, (char *)ASN1_STRING_get0_data(data), ASN1_STRING_length(data));
5264
5265 return 1;
5266} /* xe_getData() */
5267
5268
5269static int xe_getCritical(lua_State *L) {
5270 lua_pushboolean(L, X509_EXTENSION_get_critical(checksimple(L, 1, X509_EXT_CLASS)));
5271
5272 return 1;
5273} /* xe_getCritical() */
5274
5275
5276static int xe_text(lua_State *L) {
5277 X509_EXTENSION *ext = checksimple(L, 1, X509_EXT_CLASS);
5278 unsigned long flags = auxL_optunsigned(L, 2, 0, 0, ULONG_MAX);
5279 int indent = auxL_optinteger(L, 3, 0, 0, INT_MAX);
5280 BIO *bio = getbio(L);
5281 char *data;
5282 size_t len;
5283
5284 if (!X509V3_EXT_print(bio, ext, flags, indent))
5285 return auxL_error(L, auxL_EOPENSSL, "x509.extension.text");
5286
5287 len = BIO_get_mem_data(bio, &data);
5288
5289 lua_pushlstring(L, data, len);
5290
5291 return 1;
5292} /* xe_text() */
5293
5294
5295static int xe__gc(lua_State *L) {
5296 X509_EXTENSION **ud = luaL_checkudata(L, 1, X509_EXT_CLASS);
5297
5298 if (*ud) {
5299 X509_EXTENSION_free(*ud);
5300 *ud = NULL;
5301 }
5302
5303 return 0;
5304} /* xe__gc() */
5305
5306
5307static const auxL_Reg xe_methods[] = {
5308 { "getID", &xe_getID },
5309 { "getName", &xe_getName },
5310 { "getShortName", &xe_getShortName },
5311 { "getLongName", &xe_getLongName },
5312 { "getData", &xe_getData },
5313 { "getCritical", &xe_getCritical },
5314 { "text", &xe_text },
5315 { NULL, NULL },
5316};
5317
5318static const auxL_Reg xe_metatable[] = {
5319 { "__gc", &xe__gc },
5320 { NULL, NULL },
5321};
5322
5323
5324static const auxL_Reg xe_globals[] = {
5325 { "new", &xe_new },
5326 { "interpose", &xe_interpose },
5327 { NULL, NULL },
5328};
5329
5330static const auxL_IntegerReg xe_textopts[] = {
5331 { "UNKNOWN_MASK", X509V3_EXT_UNKNOWN_MASK },
5332 { "DEFAULT", X509V3_EXT_DEFAULT },
5333 { "ERROR_UNKNOWN", X509V3_EXT_ERROR_UNKNOWN },
5334 { "PARSE_UNKNOWN", X509V3_EXT_PARSE_UNKNOWN },
5335 { "DUMP_UNKNOWN", X509V3_EXT_DUMP_UNKNOWN },
5336 { NULL, 0 },
5337};
5338
5339int luaopen__openssl_x509_extension(lua_State *L) {
5340 initall(L);
5341
5342 auxL_newlib(L, xe_globals, 0);
5343 auxL_setintegers(L, xe_textopts);
5344
5345 return 1;
5346} /* luaopen__openssl_x509_extension() */
5347
5348
5349/*
5350 * X509 - openssl.x509.cert
5351 *
5352 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5353
5354static int xc_new(lua_State *L) {
5355 const char *data;
5356 size_t len;
5357 X509 **ud;
5358
5359 lua_settop(L, 2);
5360
5361 ud = prepsimple(L, X509_CERT_CLASS);
5362
5363 if ((data = luaL_optlstring(L, 1, NULL, &len))) {
5364 int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER);
5365 BIO *tmp;
5366 int ok = 0;
5367
5368 if (!(tmp = BIO_new_mem_buf((char *)data, len)))
5369 return auxL_error(L, auxL_EOPENSSL, "x509.cert.new");
5370
5371 if (type == X509_PEM || type == X509_ANY) {
5372 ok = !!(*ud = PEM_read_bio_X509(tmp, NULL, 0, "")); /* no password */
5373 }
5374
5375 if (!ok && (type == X509_DER || type == X509_ANY)) {
5376 ok = !!(*ud = d2i_X509_bio(tmp, NULL));
5377 }
5378
5379 BIO_free(tmp);
5380
5381 if (!ok)
5382 return auxL_error(L, auxL_EOPENSSL, "x509.cert.new");
5383 } else {
5384 if (!(*ud = X509_new()))
5385 return auxL_error(L, auxL_EOPENSSL, "x509.cert.new");
5386
5387 X509_gmtime_adj(X509_get_notBefore(*ud), 0);
5388 X509_gmtime_adj(X509_get_notAfter(*ud), 0);
5389 }
5390
5391 return 1;
5392} /* xc_new() */
5393
5394
5395static int xc_interpose(lua_State *L) {
5396 return interpose(L, X509_CERT_CLASS);
5397} /* xc_interpose() */
5398
5399
5400static int xc_getVersion(lua_State *L) {
5401 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5402
5403 lua_pushinteger(L, X509_get_version(crt) + 1);
5404
5405 return 1;
5406} /* xc_getVersion() */
5407
5408
5409static int xc_setVersion(lua_State *L) {
5410 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5411 int version = luaL_checkinteger(L, 2);
5412
5413 if (!X509_set_version(crt, version - 1))
5414 return luaL_error(L, "x509.cert:setVersion: %d: invalid version", version);
5415
5416 lua_pushboolean(L, 1);
5417
5418 return 1;
5419} /* xc_setVersion() */
5420
5421
5422static int xc_getSerial(lua_State *L) {
5423 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5424 BIGNUM *serial = bn_push(L);
5425 ASN1_INTEGER *i;
5426
5427 if ((i = X509_get_serialNumber(crt))) {
5428 if (!ASN1_INTEGER_to_BN(i, serial))
5429 return auxL_error(L, auxL_EOPENSSL, "x509.cert:getSerial");
5430 }
5431
5432 return 1;
5433} /* xc_getSerial() */
5434
5435
5436static int xc_setSerial(lua_State *L) {
5437 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5438 ASN1_INTEGER *serial;
5439
5440 if (!(serial = BN_to_ASN1_INTEGER(checkbig(L, 2), NULL)))
5441 goto error;
5442
5443 if (!X509_set_serialNumber(crt, serial))
5444 goto error;
5445
5446 ASN1_INTEGER_free(serial);
5447
5448 lua_pushboolean(L, 1);
5449
5450 return 1;
5451error:
5452 ASN1_INTEGER_free(serial);
5453
5454 return auxL_error(L, auxL_EOPENSSL, "x509.cert:setSerial");
5455} /* xc_setSerial() */
5456
5457
5458static int xc_digest(lua_State *L) {
5459 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5460 const char *type = luaL_optstring(L, 2, "sha1");
5461 int format = luaL_checkoption(L, 3, "x", (const char *[]){ "s", "x", "n", NULL });
5462 const EVP_MD *ctx;
5463 unsigned char md[EVP_MAX_MD_SIZE];
5464 unsigned len;
5465
5466 lua_settop(L, 3); /* self, type, hex */
5467
5468 if (!(ctx = EVP_get_digestbyname(type)))
5469 return luaL_error(L, "x509.cert:digest: %s: invalid digest type", type);
5470
5471 X509_digest(crt, ctx, md, &len);
5472
5473 switch (format) {
5474 case 2: {
5475 BIGNUM *bn = bn_push(L);
5476
5477 if (!BN_bin2bn(md, len, bn))
5478 return auxL_error(L, auxL_EOPENSSL, "x509.cert:digest");
5479
5480 break;
5481 }
5482 case 1: {
5483 static const unsigned char x[16] = "0123456789abcdef";
5484 luaL_Buffer B;
5485 unsigned i;
5486
5487#if LUA_VERSION_NUM < 502
5488 luaL_buffinit(L, &B);
5489#else
5490 luaL_buffinitsize(L, &B, 2 * len);
5491#endif
5492
5493 for (i = 0; i < len; i++) {
5494 luaL_addchar(&B, x[0x0f & (md[i] >> 4)]);
5495 luaL_addchar(&B, x[0x0f & (md[i] >> 0)]);
5496 }
5497
5498 luaL_pushresult(&B);
5499
5500 break;
5501 }
5502 default:
5503 lua_pushlstring(L, (const char *)md, len);
5504
5505 break;
5506 } /* switch() */
5507
5508 return 1;
5509} /* xc_digest() */
5510
5511
5512static _Bool isleap(int year) {
5513 if (year >= 0)
5514 return !(year % 4) && ((year % 100) || !(year % 400));
5515 else
5516 return isleap(-(year + 1));
5517} /* isleap() */
5518
5519
5520static int yday(int year, int mon, int mday) {
5521 static const int past[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
5522 int yday = past[CLAMP(mon, 0, 11)] + CLAMP(mday, 1, 31) - 1;
5523
5524 return yday + (mon > 1 && isleap(year));
5525} /* yday() */
5526
5527
5528static int tm_yday(const struct tm *tm) {
5529 return (tm->tm_yday)? tm->tm_yday : yday(1900 + tm->tm_year, tm->tm_mon, tm->tm_mday);
5530} /* tm_yday() */
5531
5532
5533static int leaps(int year) {
5534 if (year >= 0)
5535 return (year / 400) + (year / 4) - (year / 100);
5536 else
5537 return -(leaps(-(year + 1)) + 1);
5538} /* leaps() */
5539
5540
5541static double tm2unix(const struct tm *tm, int gmtoff) {
5542 int year = tm->tm_year + 1900;
5543 double ts;
5544
5545 ts = 86400.0 * 365.0 * (year - 1970);
5546 ts += 86400.0 * (leaps(year - 1) - leaps(1969));
5547 ts += 86400 * tm_yday(tm);
5548 ts += 3600 * tm->tm_hour;
5549 ts += 60 * tm->tm_min;
5550 ts += CLAMP(tm->tm_sec, 0, 59);
5551 ts += (year < 1970)? gmtoff : -gmtoff;
5552
5553 return ts;
5554} /* tm2unix() */
5555
5556
5557static _Bool scan(int *i, char **cp, int n, int signok) {
5558 int sign = 1;
5559
5560 *i = 0;
5561
5562 if (signok) {
5563 if (**cp == '-') {
5564 sign = -1;
5565 ++*cp;
5566 } else if (**cp == '+') {
5567 ++*cp;
5568 }
5569 }
5570
5571 while (n-- > 0) {
5572 if (**cp < '0' || **cp > '9')
5573 return 0;
5574
5575 *i *= 10;
5576 *i += *(*cp)++ - '0';
5577 }
5578
5579 *i *= sign;
5580
5581 return 1;
5582} /* scan() */
5583
5584
5585static double timeutc(ASN1_TIME *time) {
5586 char buf[32] = "", *cp;
5587 struct tm tm = { 0 };
5588 int gmtoff = 0, year, i;
5589
5590 if (!ASN1_TIME_check(time))
5591 return 0;
5592
5593 cp = strncpy(buf, (const char *)ASN1_STRING_get0_data((ASN1_STRING *)time), sizeof buf - 1);
5594
5595 if (ASN1_STRING_type(time) == V_ASN1_GENERALIZEDTIME) {
5596 if (!scan(&year, &cp, 4, 1))
5597 goto badfmt;
5598 } else {
5599 if (!scan(&year, &cp, 2, 0))
5600 goto badfmt;
5601 year += (year < 50)? 2000 : 1999;
5602 }
5603
5604 tm.tm_year = year - 1900;
5605
5606 if (!scan(&i, &cp, 2, 0))
5607 goto badfmt;
5608
5609 tm.tm_mon = CLAMP(i, 1, 12) - 1;
5610
5611 if (!scan(&i, &cp, 2, 0))
5612 goto badfmt;
5613
5614 tm.tm_mday = CLAMP(i, 1, 31);
5615
5616 tm.tm_yday = yday(year, tm.tm_mon, tm.tm_mday);
5617
5618 if (!scan(&i, &cp, 2, 0))
5619 goto badfmt;
5620
5621 tm.tm_hour = CLAMP(i, 0, 23);
5622
5623 if (!scan(&i, &cp, 2, 0))
5624 goto badfmt;
5625
5626 tm.tm_min = CLAMP(i, 0, 59);
5627
5628 if (*cp >= '0' && *cp <= '9') {
5629 if (!scan(&i, &cp, 2, 0))
5630 goto badfmt;
5631
5632 tm.tm_sec = CLAMP(i, 0, 59);
5633 }
5634
5635 if (*cp == '+' || *cp == '-') {
5636 int sign = (*cp++ == '-')? -1 : 1;
5637 int hh, mm;
5638
5639 if (!scan(&hh, &cp, 2, 0) || !scan(&mm, &cp, 2, 0))
5640 goto badfmt;
5641
5642 gmtoff = (CLAMP(hh, 0, 23) * 3600)
5643 + (CLAMP(mm, 0, 59) * 60);
5644
5645 gmtoff *= sign;
5646 }
5647
5648 return tm2unix(&tm, gmtoff);
5649badfmt:
5650 return INFINITY;
5651} /* timeutc() */
5652
5653
5654static int xc_getLifetime(lua_State *L) {
5655 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5656 double begin = INFINITY, end = INFINITY;
5657 ASN1_TIME *time;
5658
5659 if ((time = X509_get_notBefore(crt)))
5660 begin = timeutc(time);
5661
5662 if ((time = X509_get_notAfter(crt)))
5663 end = timeutc(time);
5664
5665 if (isfinite(begin))
5666 lua_pushnumber(L, begin);
5667 else
5668 lua_pushnil(L);
5669
5670 if (isfinite(end))
5671 lua_pushnumber(L, end);
5672 else
5673 lua_pushnil(L);
5674
5675 if (isfinite(begin) && isfinite(end) && begin <= end)
5676 lua_pushnumber(L, fabs(end - begin));
5677 else
5678 lua_pushnumber(L, 0.0);
5679
5680 return 3;
5681} /* xc_getLifetime() */
5682
5683
5684static int xc_setLifetime(lua_State *L) {
5685 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5686 double ut;
5687 const char *dt;
5688
5689 lua_settop(L, 3);
5690
5691 if (lua_isnumber(L, 2)) {
5692 ut = lua_tonumber(L, 2);
5693
5694 if (!ASN1_TIME_set(X509_get_notBefore(crt), ut))
5695 return auxL_error(L, auxL_EOPENSSL, "x509.cert:setLifetime");
5696#if 0
5697 } else if ((dt = luaL_optstring(L, 2, 0))) {
5698 if (!ASN1_TIME_set_string(X509_get_notBefore(crt), dt))
5699 return auxL_error(L, auxL_EOPENSSL, "x509.cert:setLifetime");
5700#endif
5701 }
5702
5703 if (lua_isnumber(L, 3)) {
5704 ut = lua_tonumber(L, 3);
5705
5706 if (!ASN1_TIME_set(X509_get_notAfter(crt), ut))
5707 return auxL_error(L, auxL_EOPENSSL, "x509.cert:setLifetime");
5708#if 0
5709 } else if ((dt = luaL_optstring(L, 3, 0))) {
5710 if (!ASN1_TIME_set_string(X509_get_notAfter(crt), dt))
5711 return auxL_error(L, auxL_EOPENSSL, "x509.cert:setLifetime");
5712#endif
5713 }
5714
5715 lua_pushboolean(L, 1);
5716
5717 return 1;
5718} /* xc_setLifetime() */
5719
5720
5721static int xc_getIssuer(lua_State *L) {
5722 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5723 X509_NAME *name;
5724
5725 if (!(name = X509_get_issuer_name(crt)))
5726 return 0;
5727
5728 xn_dup(L, name);
5729
5730 return 1;
5731} /* xc_getIssuer() */
5732
5733
5734static int xc_setIssuer(lua_State *L) {
5735 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5736 X509_NAME *name = checksimple(L, 2, X509_NAME_CLASS);
5737
5738 if (!X509_set_issuer_name(crt, name))
5739 return auxL_error(L, auxL_EOPENSSL, "x509.cert:setIssuer");
5740
5741 lua_pushboolean(L, 1);
5742
5743 return 1;
5744} /* xc_setIssuer() */
5745
5746
5747static int xc_getSubject(lua_State *L) {
5748 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5749 X509_NAME *name;
5750
5751 if (!(name = X509_get_subject_name(crt)))
5752 return 0;
5753
5754 xn_dup(L, name);
5755
5756 return 1;
5757} /* xc_getSubject() */
5758
5759
5760static int xc_setSubject(lua_State *L) {
5761 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5762 X509_NAME *name = checksimple(L, 2, X509_NAME_CLASS);
5763
5764 if (!X509_set_subject_name(crt, name))
5765 return auxL_error(L, auxL_EOPENSSL, "x509.cert:setSubject");
5766
5767 lua_pushboolean(L, 1);
5768
5769 return 1;
5770} /* xc_setSubject() */
5771
5772
5773static void xc_setCritical(X509 *crt, int nid, _Bool yes) {
5774 X509_EXTENSION *ext;
5775 int loc;
5776
5777 if ((loc = X509_get_ext_by_NID(crt, nid, -1)) >= 0
5778 && (ext = X509_get_ext(crt, loc)))
5779 X509_EXTENSION_set_critical(ext, yes);
5780} /* xc_setCritical() */
5781
5782
5783static _Bool xc_getCritical(X509 *crt, int nid) {
5784 X509_EXTENSION *ext;
5785 int loc;
5786
5787 if ((loc = X509_get_ext_by_NID(crt, nid, -1)) >= 0
5788 && (ext = X509_get_ext(crt, loc)))
5789 return X509_EXTENSION_get_critical(ext);
5790 else
5791 return 0;
5792} /* xc_getCritical() */
5793
5794
5795static int xc_getIssuerAlt(lua_State *L) {
5796 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5797 GENERAL_NAMES *gens;
5798
5799 if (!(gens = X509_get_ext_d2i(crt, NID_issuer_alt_name, 0, 0)))
5800 return 0;
5801
5802 gn_dup(L, gens);
5803
5804 return 1;
5805} /* xc_getIssuerAlt() */
5806
5807
5808static int xc_setIssuerAlt(lua_State *L) {
5809 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5810 GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS);
5811
5812 if (!X509_add1_ext_i2d(crt, NID_issuer_alt_name, gens, 0, X509V3_ADD_REPLACE))
5813 return auxL_error(L, auxL_EOPENSSL, "x509.altname:setIssuerAlt");
5814
5815 lua_pushboolean(L, 1);
5816
5817 return 1;
5818} /* xc_setIssuerAlt() */
5819
5820
5821static int xc_getSubjectAlt(lua_State *L) {
5822 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5823 GENERAL_NAMES *gens;
5824
5825 if (!(gens = X509_get_ext_d2i(crt, NID_subject_alt_name, 0, 0)))
5826 return 0;
5827
5828 gn_dup(L, gens);
5829
5830 return 1;
5831} /* xc_getSubjectAlt() */
5832
5833
5834static int xc_setSubjectAlt(lua_State *L) {
5835 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5836 GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS);
5837
5838 if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, X509V3_ADD_REPLACE))
5839 return auxL_error(L, auxL_EOPENSSL, "x509.altname:setSubjectAlt");
5840
5841 lua_pushboolean(L, 1);
5842
5843 return 1;
5844} /* xc_setSubjectAlt() */
5845
5846
5847static int xc_getIssuerAltCritical(lua_State *L) {
5848 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5849
5850 lua_pushboolean(L, xc_getCritical(crt, NID_issuer_alt_name));
5851
5852 return 1;
5853} /* xc_getIssuerAltCritical() */
5854
5855
5856static int xc_setIssuerAltCritical(lua_State *L) {
5857 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5858
5859 luaL_checkany(L, 2);
5860 xc_setCritical(crt, NID_issuer_alt_name, lua_toboolean(L, 2));
5861
5862 lua_pushboolean(L, 1);
5863
5864 return 1;
5865} /* xc_setIssuerAltCritical() */
5866
5867
5868static int xc_getSubjectAltCritical(lua_State *L) {
5869 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5870
5871 lua_pushboolean(L, xc_getCritical(crt, NID_subject_alt_name));
5872
5873 return 1;
5874} /* xc_getSubjectAltCritical() */
5875
5876
5877static int xc_setSubjectAltCritical(lua_State *L) {
5878 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5879
5880 luaL_checkany(L, 2);
5881 xc_setCritical(crt, NID_subject_alt_name, lua_toboolean(L, 2));
5882
5883 lua_pushboolean(L, 1);
5884
5885 return 1;
5886} /* xc_setSubjectAltCritical() */
5887
5888
5889static int xc_getBasicConstraint(lua_State *L) {
5890 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5891 BASIC_CONSTRAINTS *bs;
5892 int CA, pathLen;
5893
5894 if (!(bs = X509_get_ext_d2i(crt, NID_basic_constraints, 0, 0))) {
5895 /* FIXME: detect error or just non-existent */
5896
5897 if (lua_gettop(L) > 1)
5898 return 0;
5899
5900 lua_newtable(L);
5901
5902 return 1;
5903 }
5904
5905 CA = bs->ca;
5906 pathLen = ASN1_INTEGER_get(bs->pathlen);
5907
5908 BASIC_CONSTRAINTS_free(bs);
5909
5910 if (lua_gettop(L) > 1) {
5911 int n = 0, i, top;
5912
5913 for (i = 2, top = lua_gettop(L); i <= top; i++) {
5914 switch (auxL_checkoption(L, i, 0, (const char *[]){ "CA", "pathLen", "pathLenConstraint", NULL }, 1)) {
5915 case 0:
5916 lua_pushboolean(L, CA);
5917 n++;
5918 break;
5919 case 1:
5920 /* FALL THROUGH */
5921 case 2:
5922 lua_pushinteger(L, pathLen);
5923 n++;
5924 break;
5925 }
5926 }
5927
5928 return n;
5929 } else {
5930 lua_newtable(L);
5931
5932 lua_pushboolean(L, CA);
5933 lua_setfield(L, -2, "CA");
5934
5935 lua_pushinteger(L, pathLen);
5936 lua_setfield(L, -2, "pathLen");
5937
5938 return 1;
5939 }
5940} /* xc_getBasicConstraint() */
5941
5942
5943static int xc_setBasicConstraint(lua_State *L) {
5944 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5945 BASIC_CONSTRAINTS *bs = 0;
5946 int CA = -1, pathLen = -1;
5947 int critical = 0;
5948
5949 luaL_checkany(L, 2);
5950
5951 if (lua_istable(L, 2)) {
5952 lua_getfield(L, 2, "CA");
5953 if (!lua_isnil(L, -1))
5954 CA = lua_toboolean(L, -1);
5955 lua_pop(L, 1);
5956
5957 lua_getfield(L, 2, "pathLen");
5958 pathLen = luaL_optinteger(L, -1, pathLen);
5959 lua_pop(L, 1);
5960
5961 lua_getfield(L, 2, "pathLenConstraint");
5962 pathLen = luaL_optinteger(L, -1, pathLen);
5963 lua_pop(L, 1);
5964
5965 if (!(bs = BASIC_CONSTRAINTS_new()))
5966 goto error;
5967 } else {
5968 lua_settop(L, 3);
5969
5970 switch (auxL_checkoption(L, 2, 0, (const char *[]){ "CA", "pathLen", "pathLenConstraint", NULL }, 1)) {
5971 case 0:
5972 luaL_checktype(L, 3, LUA_TBOOLEAN);
5973 CA = lua_toboolean(L, 3);
5974
5975 break;
5976 case 1:
5977 /* FALL THROUGH */
5978 case 2:
5979 pathLen = luaL_checkinteger(L, 3);
5980
5981 break;
5982 }
5983
5984 if (!(bs = X509_get_ext_d2i(crt, NID_basic_constraints, &critical, 0))) {
5985 /* FIXME: detect whether error or just non-existent */
5986 if (!(bs = BASIC_CONSTRAINTS_new()))
5987 goto error;
5988 }
5989 }
5990
5991 if (CA != -1)
5992 bs->ca = CA;
5993
5994 if (pathLen >= 0) {
5995 ASN1_INTEGER_free(bs->pathlen);
5996
5997 if (!(bs->pathlen = ASN1_STRING_type_new(V_ASN1_INTEGER)))
5998 goto error;
5999
6000 if (!ASN1_INTEGER_set(bs->pathlen, pathLen))
6001 goto error;
6002 }
6003
6004 if (!X509_add1_ext_i2d(crt, NID_basic_constraints, bs, critical, X509V3_ADD_REPLACE))
6005 goto error;
6006
6007 BASIC_CONSTRAINTS_free(bs);
6008
6009 lua_pushboolean(L, 1);
6010
6011 return 1;
6012error:
6013 BASIC_CONSTRAINTS_free(bs);
6014
6015 return auxL_error(L, auxL_EOPENSSL, "x509.cert:setBasicConstraint");
6016} /* xc_setBasicConstraint() */
6017
6018
6019static int xc_getBasicConstraintsCritical(lua_State *L) {
6020 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6021
6022 lua_pushboolean(L, xc_getCritical(crt, NID_basic_constraints));
6023
6024 return 1;
6025} /* xc_getBasicConstraintsCritical() */
6026
6027
6028static int xc_setBasicConstraintsCritical(lua_State *L) {
6029 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6030
6031 luaL_checkany(L, 2);
6032 xc_setCritical(crt, NID_basic_constraints, lua_toboolean(L, 2));
6033
6034 lua_pushboolean(L, 1);
6035
6036 return 1;
6037} /* xc_setBasicConstraintsCritical() */
6038
6039
6040static int xc_addExtension(lua_State *L) {
6041 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6042 X509_EXTENSION *ext = checksimple(L, 2, X509_EXT_CLASS);
6043
6044 /* NOTE: Will dup extension in X509v3_add_ext. */
6045 if (!X509_add_ext(crt, ext, -1))
6046 return auxL_error(L, auxL_EOPENSSL, "x509.cert:addExtension");
6047
6048 lua_pushboolean(L, 1);
6049
6050 return 1;
6051} /* xc_addExtension() */
6052
6053
6054static int xc_getExtension(lua_State *L) {
6055 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6056 X509_EXTENSION *ext = NULL, **ud;
6057 int i;
6058
6059 luaL_checkany(L, 2);
6060
6061 if (lua_type(L, 2) == LUA_TNUMBER) {
6062 /* NB: Lua 1-based indexing */
6063 i = auxL_checkinteger(L, 2, 1, INT_MAX) - 1;
6064 } else {
6065 ASN1_OBJECT *obj;
6066
6067 if (!auxS_txt2obj(&obj, luaL_checkstring(L, 2))) {
6068 goto error;
6069 } else if (!obj) {
6070 goto undef;
6071 }
6072
6073 i = X509_get_ext_by_OBJ(crt, obj, -1);
6074
6075 ASN1_OBJECT_free(obj);
6076 }
6077
6078 ud = prepsimple(L, X509_EXT_CLASS);
6079
6080 if (i < 0 || !(ext = X509_get0_ext(crt, i)))
6081 goto undef;
6082
6083 if (!(*ud = X509_EXTENSION_dup(ext)))
6084 goto error;
6085
6086 return 1;
6087undef:
6088 return 0;
6089error:
6090 return auxL_error(L, auxL_EOPENSSL, "x509.cert:getExtension");
6091} /* xc_getExtension() */
6092
6093
6094static int xc_getExtensionCount(lua_State *L) {
6095 auxL_pushinteger(L, X509_get_ext_count(checksimple(L, 1, X509_CERT_CLASS)));
6096
6097 return 1;
6098} /* xc_getExtensionCount() */
6099
6100
6101static int sk_openssl_string__gc(lua_State *L) {
6102 STACK_OF(OPENSSL_STRING) **res = lua_touserdata(L, 1);
6103
6104 if (*res) {
6105 sk_OPENSSL_STRING_free(*res);
6106 *res = NULL;
6107 }
6108
6109 return 0;
6110} /* sk_openssl_string__gc() */
6111
6112
6113static int xc_getOCSP(lua_State *L) {
6114 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6115 STACK_OF(OPENSSL_STRING) **res = prepsimple(L, NULL, &sk_openssl_string__gc);
6116 int num, i;
6117
6118 *res = X509_get1_ocsp(crt);
6119 if (!*res)
6120 return 0;
6121
6122 num = sk_OPENSSL_STRING_num(*res);
6123 luaL_checkstack(L, num, "too many authorityInfoAccess");
6124 for (i = 0; i < num; i++) {
6125 lua_pushstring(L, sk_OPENSSL_STRING_value(*res, i));
6126 }
6127
6128 sk_OPENSSL_STRING_free(*res);
6129 *res = NULL;
6130
6131 return num;
6132} /* xc_getOCSP */
6133
6134
6135static int xc_isIssuedBy(lua_State *L) {
6136 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6137 X509 *issuer = checksimple(L, 2, X509_CERT_CLASS);
6138 EVP_PKEY *key;
6139 int ok, why = 0;
6140
6141 ERR_clear_error();
6142
6143 if (X509_V_OK != (why = X509_check_issued(issuer, crt)))
6144 goto done;
6145
6146 if (!(key = X509_get_pubkey(issuer))) {
6147 why = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
6148 goto done;
6149 }
6150
6151 ok = (1 == X509_verify(crt, key));
6152
6153 EVP_PKEY_free(key);
6154
6155 if (!ok)
6156 why = X509_V_ERR_CERT_SIGNATURE_FAILURE;
6157
6158done:
6159 if (why != X509_V_OK) {
6160 lua_pushboolean(L, 0);
6161 lua_pushstring(L, X509_verify_cert_error_string(why));
6162
6163 return 2;
6164 } else {
6165 lua_pushboolean(L, 1);
6166
6167 return 1;
6168 }
6169} /* xc_isIssuedBy() */
6170
6171
6172static int xc_getPublicKey(lua_State *L) {
6173 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6174 EVP_PKEY **key = prepsimple(L, PKEY_CLASS);
6175
6176 if (!(*key = X509_get_pubkey(crt)))
6177 return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKey");
6178
6179 return 1;
6180} /* xc_getPublicKey() */
6181
6182
6183static int xc_setPublicKey(lua_State *L) {
6184 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6185 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
6186
6187 if (!X509_set_pubkey(crt, key))
6188 return auxL_error(L, auxL_EOPENSSL, "x509.cert:setPublicKey");
6189
6190 lua_pushboolean(L, 1);
6191
6192 return 1;
6193} /* xc_setPublicKey() */
6194
6195
6196static int xc_getPublicKeyDigest(lua_State *L) {
6197 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6198 EVP_PKEY *key;
6199 const EVP_MD *md;
6200 ASN1_BIT_STRING *bitstr;
6201 unsigned char digest[EVP_MAX_MD_SIZE];
6202 unsigned int len;
6203
6204 if (!(key = X509_get_pubkey(crt)))
6205 return luaL_argerror(L, 1, "no public key");
6206 md = auxL_optdigest(L, 2, key, NULL);
6207 bitstr = X509_get0_pubkey_bitstr(crt);
6208
6209 if (!EVP_Digest(bitstr->data, bitstr->length, digest, &len, md, NULL))
6210 return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKeyDigest");
6211 lua_pushlstring(L, (char *)digest, len);
6212
6213 return 1;
6214} /* xc_getPublicKeyDigest() */
6215
6216
6217static int xc_getSignatureName(lua_State *L) {
6218 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6219 int nid;
6220
6221 if (NID_undef == (nid = X509_get_signature_nid(crt)))
6222 return 0;
6223
6224 auxL_pushnid(L, nid);
6225
6226 return 1;
6227} /* xc_getSignatureName() */
6228
6229
6230static int xc_sign(lua_State *L) {
6231 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6232 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
6233
6234 if (!X509_sign(crt, key, auxL_optdigest(L, 3, key, NULL)))
6235 return auxL_error(L, auxL_EOPENSSL, "x509.cert:sign");
6236
6237 lua_pushboolean(L, 1);
6238
6239 return 1;
6240} /* xc_sign() */
6241
6242
6243static int xc_text(lua_State *L) {
6244 static const struct { const char *kw; unsigned int flag; } map[] = {
6245 { "no_header", X509_FLAG_NO_HEADER },
6246 { "no_version", X509_FLAG_NO_VERSION },
6247 { "no_serial", X509_FLAG_NO_SERIAL },
6248 { "no_signame", X509_FLAG_NO_SIGNAME },
6249 { "no_validity", X509_FLAG_NO_VALIDITY },
6250 { "no_subject", X509_FLAG_NO_SUBJECT },
6251 { "no_issuer", X509_FLAG_NO_ISSUER },
6252 { "no_pubkey", X509_FLAG_NO_PUBKEY },
6253 { "no_extensions", X509_FLAG_NO_EXTENSIONS },
6254 { "no_sigdump", X509_FLAG_NO_SIGDUMP },
6255 { "no_aux", X509_FLAG_NO_AUX },
6256 { "no_attributes", X509_FLAG_NO_ATTRIBUTES },
6257 { "ext_default", X509V3_EXT_DEFAULT },
6258 { "ext_error", X509V3_EXT_ERROR_UNKNOWN },
6259 { "ext_parse", X509V3_EXT_PARSE_UNKNOWN },
6260 { "ext_dump", X509V3_EXT_DUMP_UNKNOWN }
6261 };
6262
6263 lua_settop(L, 2);
6264
6265 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6266
6267 unsigned int flags = 0;
6268 const char *kw;
6269 int found;
6270 unsigned int i;
6271
6272 BIO *bio = getbio(L);
6273 char *data;
6274 long len;
6275
6276 if (!lua_isnil(L, 2)) {
6277 lua_pushnil(L);
6278 while (lua_next(L, 2)) {
6279 kw = luaL_checkstring(L, -1);
6280 found = 0;
6281 for (i = 0; i < countof(map); i++)
6282 if (!strcmp(kw, map[i].kw)) {
6283 flags |= map[i].flag;
6284 found = 1;
6285 }
6286 if (!found)
6287 luaL_argerror(L, 2, lua_pushfstring(L, "invalid flag: %s", kw));
6288 lua_pop(L, 1);
6289 }
6290 }
6291
6292 if (!X509_print_ex(bio, crt, 0, flags))
6293 return auxL_error(L, auxL_EOPENSSL, "x509.cert:text");
6294
6295 len = BIO_get_mem_data(bio, &data);
6296
6297 lua_pushlstring(L, data, len);
6298
6299 return 1;
6300} /* xc_text() */
6301
6302
6303static int xc__tostring(lua_State *L) {
6304 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
6305 int type = optencoding(L, 2, "pem", X509_PEM|X509_DER);
6306 BIO *bio = getbio(L);
6307 char *data;
6308 long len;
6309
6310 switch (type) {
6311 case X509_PEM:
6312 if (!PEM_write_bio_X509(bio, crt))
6313 return auxL_error(L, auxL_EOPENSSL, "x509.cert:__tostring");
6314 break;
6315 case X509_DER:
6316 if (!i2d_X509_bio(bio, crt))
6317 return auxL_error(L, auxL_EOPENSSL, "x509.cert:__tostring");
6318 break;
6319 } /* switch() */
6320
6321 len = BIO_get_mem_data(bio, &data);
6322
6323 lua_pushlstring(L, data, len);
6324
6325 return 1;
6326} /* xc__tostring() */
6327
6328
6329static int xc__gc(lua_State *L) {
6330 X509 **ud = luaL_checkudata(L, 1, X509_CERT_CLASS);
6331
6332 if (*ud) {
6333 X509_free(*ud);
6334 *ud = NULL;
6335 }
6336
6337 return 0;
6338} /* xc__gc() */
6339
6340
6341static const auxL_Reg xc_methods[] = {
6342 { "getVersion", &xc_getVersion },
6343 { "setVersion", &xc_setVersion },
6344 { "getSerial", &xc_getSerial },
6345 { "setSerial", &xc_setSerial },
6346 { "digest", &xc_digest },
6347 { "getLifetime", &xc_getLifetime },
6348 { "setLifetime", &xc_setLifetime },
6349 { "getIssuer", &xc_getIssuer },
6350 { "setIssuer", &xc_setIssuer },
6351 { "getSubject", &xc_getSubject },
6352 { "setSubject", &xc_setSubject },
6353 { "getIssuerAlt", &xc_getIssuerAlt },
6354 { "setIssuerAlt", &xc_setIssuerAlt },
6355 { "getSubjectAlt", &xc_getSubjectAlt },
6356 { "setSubjectAlt", &xc_setSubjectAlt },
6357 { "getIssuerAltCritical", &xc_getIssuerAltCritical },
6358 { "setIssuerAltCritical", &xc_setIssuerAltCritical },
6359 { "getSubjectAltCritical", &xc_getSubjectAltCritical },
6360 { "setSubjectAltCritical", &xc_setSubjectAltCritical },
6361 { "getBasicConstraints", &xc_getBasicConstraint },
6362 { "getBasicConstraint", &xc_getBasicConstraint },
6363 { "setBasicConstraints", &xc_setBasicConstraint },
6364 { "setBasicConstraint", &xc_setBasicConstraint },
6365 { "getBasicConstraintsCritical", &xc_getBasicConstraintsCritical },
6366 { "setBasicConstraintsCritical", &xc_setBasicConstraintsCritical },
6367 { "addExtension", &xc_addExtension },
6368 { "getExtension", &xc_getExtension },
6369 { "getExtensionCount", &xc_getExtensionCount },
6370 { "getOCSP", &xc_getOCSP },
6371 { "isIssuedBy", &xc_isIssuedBy },
6372 { "getPublicKey", &xc_getPublicKey },
6373 { "setPublicKey", &xc_setPublicKey },
6374 { "getPublicKeyDigest", &xc_getPublicKeyDigest },
6375 { "getSignatureName", &xc_getSignatureName },
6376 { "sign", &xc_sign },
6377 { "text", &xc_text },
6378 { "tostring", &xc__tostring },
6379 { NULL, NULL },
6380};
6381
6382static const auxL_Reg xc_metatable[] = {
6383 { "__tostring", &xc__tostring },
6384 { "__gc", &xc__gc },
6385 { NULL, NULL },
6386};
6387
6388
6389static const auxL_Reg xc_globals[] = {
6390 { "new", &xc_new },
6391 { "interpose", &xc_interpose },
6392 { NULL, NULL },
6393};
6394
6395int luaopen__openssl_x509_cert(lua_State *L) {
6396 initall(L);
6397
6398 auxL_newlib(L, xc_globals, 0);
6399
6400 return 1;
6401} /* luaopen__openssl_x509_cert() */
6402
6403
6404/*
6405 * X509_REQ - openssl.x509.csr
6406 *
6407 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
6408
6409static int xr_new(lua_State *L) {
6410 const char *data;
6411 size_t len;
6412 X509_REQ **ud;
6413 X509 *crt;
6414
6415 lua_settop(L, 2);
6416
6417 ud = prepsimple(L, X509_CSR_CLASS);
6418
6419 if ((crt = testsimple(L, 1, X509_CERT_CLASS))) {
6420 if (!(*ud = X509_to_X509_REQ(crt, 0, 0)))
6421 return auxL_error(L, auxL_EOPENSSL, "x509.csr.new");
6422 } else if ((data = luaL_optlstring(L, 1, NULL, &len))) {
6423 int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER);
6424 BIO *tmp;
6425 int ok = 0;
6426
6427 if (!(tmp = BIO_new_mem_buf((char *)data, len)))
6428 return auxL_error(L, auxL_EOPENSSL, "x509.csr.new");
6429
6430 if (type == X509_PEM || type == X509_ANY) {
6431 ok = !!(*ud = PEM_read_bio_X509_REQ(tmp, NULL, 0, "")); /* no password */
6432 }
6433
6434 if (!ok && (type == X509_DER || type == X509_ANY)) {
6435 ok = !!(*ud = d2i_X509_REQ_bio(tmp, NULL));
6436 }
6437
6438 BIO_free(tmp);
6439
6440 if (!ok)
6441 return auxL_error(L, auxL_EOPENSSL, "x509.csr.new");
6442 } else {
6443 if (!(*ud = X509_REQ_new()))
6444 return auxL_error(L, auxL_EOPENSSL, "x509.csr.new");
6445 }
6446
6447 return 1;
6448} /* xr_new() */
6449
6450
6451static int xr_interpose(lua_State *L) {
6452 return interpose(L, X509_CSR_CLASS);
6453} /* xr_interpose() */
6454
6455
6456static int xr_getVersion(lua_State *L) {
6457 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6458
6459 lua_pushinteger(L, X509_REQ_get_version(csr) + 1);
6460
6461 return 1;
6462} /* xr_getVersion() */
6463
6464
6465static int xr_setVersion(lua_State *L) {
6466 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6467 int version = luaL_checkinteger(L, 2);
6468
6469 if (!X509_REQ_set_version(csr, version - 1))
6470 return luaL_error(L, "x509.csr:setVersion: %d: invalid version", version);
6471
6472 lua_pushboolean(L, 1);
6473
6474 return 1;
6475} /* xr_setVersion() */
6476
6477
6478static int xr_getSubject(lua_State *L) {
6479 X509_REQ *crt = checksimple(L, 1, X509_CSR_CLASS);
6480 X509_NAME *name;
6481
6482 if (!(name = X509_REQ_get_subject_name(crt)))
6483 return 0;
6484
6485 xn_dup(L, name);
6486
6487 return 1;
6488} /* xr_getSubject() */
6489
6490
6491static int xr_setSubject(lua_State *L) {
6492 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6493 X509_NAME *name = checksimple(L, 2, X509_NAME_CLASS);
6494
6495 if (!X509_REQ_set_subject_name(csr, name))
6496 return auxL_error(L, auxL_EOPENSSL, "x509.csr:setSubject");
6497
6498 lua_pushboolean(L, 1);
6499
6500 return 1;
6501} /* xr_setSubject() */
6502
6503
6504static int xr_getPublicKey(lua_State *L) {
6505 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6506 EVP_PKEY **key = prepsimple(L, PKEY_CLASS);
6507
6508 if (!(*key = X509_REQ_get_pubkey(csr)))
6509 return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKey");
6510
6511 return 1;
6512} /* xr_getPublicKey() */
6513
6514
6515static int xr_setPublicKey(lua_State *L) {
6516 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6517 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
6518
6519 if (!X509_REQ_set_pubkey(csr, key))
6520 return auxL_error(L, auxL_EOPENSSL, "x509.csr:setPublicKey");
6521
6522 lua_pushboolean(L, 1);
6523
6524 return 1;
6525} /* xr_setPublicKey() */
6526
6527
6528static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, void* value) {
6529 STACK_OF(X509_EXTENSION) *sk = NULL;
6530 int has_attrs=0;
6531
6532 /*
6533 * Replace existing if it's there. Extensions are stored in a CSR in
6534 * an interesting way:
6535 *
6536 * They are stored as a list under either (most likely) the
6537 * "official" NID_ext_req or under NID_ms_ext_req which means
6538 * everything is stored under a list in a single "attribute" so we
6539 * can't use X509_REQ_add1_attr or similar.
6540 *
6541 * Instead we have to get the extensions, find and replace the SAN
6542 * if it's in there, then *replace* the extensions in the list of
6543 * attributes. (If we just try to add it the old ones are found
6544 * first and don't take priority.)
6545 */
6546 has_attrs = X509_REQ_get_attr_count(csr);
6547
6548 sk = X509_REQ_get_extensions(csr);
6549 if (!X509V3_add1_i2d(&sk, target_nid, value, 0, X509V3_ADD_REPLACE))
6550 goto error;
6551 if (X509_REQ_add_extensions(csr, sk) == 0)
6552 goto error;
6553 sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
6554 sk = NULL;
6555
6556 /*
6557 * Delete the old extensions attribute, so that the one we just
6558 * added takes priority.
6559 */
6560 if (has_attrs) {
6561 X509_ATTRIBUTE *attr = NULL;
6562 int idx, *pnid;
6563
6564 for (pnid = X509_REQ_get_extension_nids(); *pnid != NID_undef; pnid++) {
6565 idx = X509_REQ_get_attr_by_NID(csr, *pnid, -1);
6566 if (idx == -1)
6567 continue;
6568 if (!(attr = X509_REQ_delete_attr(csr, idx)))
6569 goto error;
6570 X509_ATTRIBUTE_free(attr);
6571 break;
6572 }
6573 if (!attr)
6574 goto error;
6575 }
6576
6577 /*
6578 * We have to mark the encoded form as invalid, otherwise when we
6579 * write it out again it will use the loaded version.
6580 */
6581#if HAVE_I2D_RE_X509_REQ_TBS
6582 (void)i2d_re_X509_REQ_tbs(csr, NULL); /* sets csr->req_info->enc.modified */
6583#else
6584 csr->req_info->enc.modified = 1;
6585#endif
6586
6587 lua_pushboolean(L, 1);
6588
6589 return 1;
6590error:
6591 if (sk)
6592 sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
6593
6594 return auxL_error(L, auxL_EOPENSSL, "x509.csr.setExtensionByNid");
6595} /* xr_setExtensionByNid() */
6596
6597
6598static int xr_setSubjectAlt(lua_State *L) {
6599 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6600 GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS);
6601
6602 return xr_setExtensionByNid(L, csr, NID_subject_alt_name, gens);
6603} /* xr_setSubjectAlt */
6604
6605
6606static int xr_getSubjectAlt(lua_State *L) {
6607 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6608 STACK_OF(X509_EXTENSION) *exts;
6609 GENERAL_NAMES *gens;
6610
6611 exts = X509_REQ_get_extensions(csr);
6612 gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
6613 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
6614 if (!gens) goto error;
6615
6616 gn_dup(L, gens);
6617
6618 return 1;
6619error:
6620 return 0;
6621} /* xr_getSubjectAlt() */
6622
6623
6624
6625static int xr_sign(lua_State *L) {
6626 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6627 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
6628
6629 if (!X509_REQ_sign(csr, key, auxL_optdigest(L, 3, key, NULL)))
6630 return auxL_error(L, auxL_EOPENSSL, "x509.csr:sign");
6631
6632 lua_pushboolean(L, 1);
6633
6634 return 1;
6635} /* xr_sign() */
6636
6637
6638static int xr__tostring(lua_State *L) {
6639 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6640 int type = optencoding(L, 2, "pem", X509_PEM|X509_DER);
6641 BIO *bio = getbio(L);
6642 char *data;
6643 long len;
6644
6645 switch (type) {
6646 case X509_PEM:
6647 if (!PEM_write_bio_X509_REQ(bio, csr))
6648 return auxL_error(L, auxL_EOPENSSL, "x509.csr:__tostring");
6649 break;
6650 case X509_DER:
6651 if (!i2d_X509_REQ_bio(bio, csr))
6652 return auxL_error(L, auxL_EOPENSSL, "x509.csr:__tostring");
6653 break;
6654 } /* switch() */
6655
6656 len = BIO_get_mem_data(bio, &data);
6657
6658 lua_pushlstring(L, data, len);
6659
6660 return 1;
6661} /* xr__tostring() */
6662
6663
6664static int xr__gc(lua_State *L) {
6665 X509_REQ **ud = luaL_checkudata(L, 1, X509_CSR_CLASS);
6666
6667 if (*ud) {
6668 X509_REQ_free(*ud);
6669 *ud = NULL;
6670 }
6671
6672 return 0;
6673} /* xr__gc() */
6674
6675static const auxL_Reg xr_methods[] = {
6676 { "getVersion", &xr_getVersion },
6677 { "setVersion", &xr_setVersion },
6678 { "getSubject", &xr_getSubject },
6679 { "setSubject", &xr_setSubject },
6680 { "getPublicKey", &xr_getPublicKey },
6681 { "setPublicKey", &xr_setPublicKey },
6682 { "getSubjectAlt", &xr_getSubjectAlt },
6683 { "setSubjectAlt", &xr_setSubjectAlt },
6684 { "sign", &xr_sign },
6685 { "tostring", &xr__tostring },
6686 { NULL, NULL },
6687};
6688
6689static const auxL_Reg xr_metatable[] = {
6690 { "__tostring", &xr__tostring },
6691 { "__gc", &xr__gc },
6692 { NULL, NULL },
6693};
6694
6695
6696static const auxL_Reg xr_globals[] = {
6697 { "new", &xr_new },
6698 { "interpose", &xr_interpose },
6699 { NULL, NULL },
6700};
6701
6702int luaopen__openssl_x509_csr(lua_State *L) {
6703 initall(L);
6704
6705 auxL_newlib(L, xr_globals, 0);
6706
6707 return 1;
6708} /* luaopen__openssl_x509_csr() */
6709
6710
6711/*
6712 * X509_CRL - openssl.x509.crl
6713 *
6714 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
6715
6716static int xx_new(lua_State *L) {
6717 const char *data;
6718 size_t len;
6719 X509_CRL **ud;
6720
6721 lua_settop(L, 2);
6722
6723 ud = prepsimple(L, X509_CRL_CLASS);
6724
6725 if ((data = luaL_optlstring(L, 1, NULL, &len))) {
6726 int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER);
6727 BIO *tmp;
6728 int ok = 0;
6729
6730 if (!(tmp = BIO_new_mem_buf((char *)data, len)))
6731 return auxL_error(L, auxL_EOPENSSL, "x509.crl.new");
6732
6733 if (type == X509_PEM || type == X509_ANY) {
6734 ok = !!(*ud = PEM_read_bio_X509_CRL(tmp, NULL, 0, "")); /* no password */
6735 }
6736
6737 if (!ok && (type == X509_DER || type == X509_ANY)) {
6738 ok = !!(*ud = d2i_X509_CRL_bio(tmp, NULL));
6739 }
6740
6741 BIO_free(tmp);
6742
6743 if (!ok)
6744 return auxL_error(L, auxL_EOPENSSL, "x509.crl.new");
6745 } else {
6746 if (!(*ud = X509_CRL_new()))
6747 return auxL_error(L, auxL_EOPENSSL, "x509.crl.new");
6748
6749 X509_gmtime_adj(X509_CRL_get_lastUpdate(*ud), 0);
6750 }
6751
6752 return 1;
6753} /* xx_new() */
6754
6755
6756static int xx_interpose(lua_State *L) {
6757 return interpose(L, X509_CRL_CLASS);
6758} /* xx_interpose() */
6759
6760
6761static int xx_getVersion(lua_State *L) {
6762 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6763
6764 lua_pushinteger(L, X509_CRL_get_version(crl) + 1);
6765
6766 return 1;
6767} /* xx_getVersion() */
6768
6769
6770static int xx_setVersion(lua_State *L) {
6771 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6772 int version = luaL_checkinteger(L, 2);
6773
6774 if (!X509_CRL_set_version(crl, version - 1))
6775 return luaL_error(L, "x509.crl:setVersion: %d: invalid version", version);
6776
6777 lua_pushboolean(L, 1);
6778
6779 return 1;
6780} /* xx_setVersion() */
6781
6782
6783static int xx_getLastUpdate(lua_State *L) {
6784 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6785 double updated = INFINITY;
6786 ASN1_TIME *time;
6787
6788 if ((time = X509_CRL_get_lastUpdate(crl)))
6789 updated = timeutc(time);
6790
6791 if (isfinite(updated))
6792 lua_pushnumber(L, updated);
6793 else
6794 lua_pushnil(L);
6795
6796 return 1;
6797} /* xx_getLastUpdate() */
6798
6799
6800static int xx_setLastUpdate(lua_State *L) {
6801 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6802 double updated = luaL_checknumber(L, 2);
6803
6804 /* lastUpdate always present */
6805 if (!ASN1_TIME_set(X509_CRL_get_lastUpdate(crl), updated))
6806 return auxL_error(L, auxL_EOPENSSL, "x509.crl:setLastUpdate");
6807
6808 lua_pushboolean(L, 1);
6809
6810 return 1;
6811} /* xx_setLastUpdate() */
6812
6813
6814static int xx_getNextUpdate(lua_State *L) {
6815 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6816 double updateby = INFINITY;
6817 ASN1_TIME *time;
6818
6819 if ((time = X509_CRL_get_nextUpdate(crl)))
6820 updateby = timeutc(time);
6821
6822 if (isfinite(updateby))
6823 lua_pushnumber(L, updateby);
6824 else
6825 lua_pushnil(L);
6826
6827 return 1;
6828} /* xx_getNextUpdate() */
6829
6830
6831static int xx_setNextUpdate(lua_State *L) {
6832 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6833 double updateby = luaL_checknumber(L, 2);
6834 ASN1_TIME *time = NULL;
6835
6836 if (X509_CRL_get_nextUpdate(crl)) {
6837 if (!ASN1_TIME_set(X509_CRL_get_nextUpdate(crl), updateby))
6838 goto error;
6839 } else {
6840 if (!(time = ASN1_TIME_new()))
6841 goto error;
6842
6843 if (!(ASN1_TIME_set(time, updateby)))
6844 goto error;
6845
6846 if (!X509_CRL_set_nextUpdate(crl, time))
6847 goto error;
6848
6849 time = NULL;
6850 }
6851
6852 lua_pushboolean(L, 1);
6853
6854 return 1;
6855error:
6856 if (time)
6857 ASN1_TIME_free(time);
6858
6859 return auxL_error(L, auxL_EOPENSSL, "x509.crl:setNextUpdate");
6860} /* xx_setNextUpdate() */
6861
6862
6863static int xx_getIssuer(lua_State *L) {
6864 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6865 X509_NAME *name;
6866
6867 if (!(name = X509_CRL_get_issuer(crl)))
6868 return 0;
6869
6870 xn_dup(L, name);
6871
6872 return 1;
6873} /* xx_getIssuer() */
6874
6875
6876static int xx_setIssuer(lua_State *L) {
6877 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6878 X509_NAME *name = checksimple(L, 2, X509_NAME_CLASS);
6879
6880 if (!X509_CRL_set_issuer_name(crl, name))
6881 return auxL_error(L, auxL_EOPENSSL, "x509.crl:setIssuer");
6882
6883 lua_pushboolean(L, 1);
6884
6885 return 1;
6886} /* xx_setIssuer() */
6887
6888
6889static int xx_add(lua_State *L) {
6890 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6891 BIGNUM *bn = checkbig(L, 2);
6892 double ut = luaL_optnumber(L, 3, time(NULL));
6893 X509_REVOKED *rev = NULL;
6894 ASN1_INTEGER *serial = NULL;
6895 ASN1_TIME *date = NULL;
6896
6897 if (!(rev = X509_REVOKED_new()))
6898 goto error;
6899
6900 if (!(serial = BN_to_ASN1_INTEGER(bn, NULL)))
6901 goto error;
6902
6903 if (!X509_REVOKED_set_serialNumber(rev, serial)) /* duplicates serial */
6904 goto error;
6905
6906 ASN1_INTEGER_free(serial);
6907 serial = NULL;
6908
6909 if (!(date = ASN1_TIME_new()))
6910 goto error;
6911
6912 if (!ASN1_TIME_set(date, ut))
6913 goto error;
6914
6915 if (!X509_REVOKED_set_revocationDate(rev, date)) /* duplicates date */
6916 goto error;
6917
6918 ASN1_TIME_free(date);
6919 date = NULL;
6920
6921 if (!X509_CRL_add0_revoked(crl, rev)) /* takes ownership of rev */
6922 goto error;
6923
6924 lua_pushboolean(L, 1);
6925
6926 return 1;
6927error:
6928 if (date)
6929 ASN1_TIME_free(date);
6930 if (serial)
6931 ASN1_INTEGER_free(serial);
6932 if (rev)
6933 X509_REVOKED_free(rev);
6934
6935 return auxL_error(L, auxL_EOPENSSL, "x509.crl:add");
6936} /* xx_add() */
6937
6938
6939static int xx_addExtension(lua_State *L) {
6940 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6941 X509_EXTENSION *ext = checksimple(L, 2, X509_EXT_CLASS);
6942
6943 /* NOTE: Will dup extension in X509v3_add_ext. */
6944 if (!X509_CRL_add_ext(crl, ext, -1))
6945 return auxL_error(L, auxL_EOPENSSL, "x509.crl:addExtension");
6946
6947 lua_pushboolean(L, 1);
6948
6949 return 1;
6950} /* xx_addExtension() */
6951
6952
6953static int xx_getExtension(lua_State *L) {
6954 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6955 X509_EXTENSION *ext = NULL, **ud;
6956 int i;
6957
6958 luaL_checkany(L, 2);
6959
6960 if (lua_type(L, 2) == LUA_TNUMBER) {
6961 /* NB: Lua 1-based indexing */
6962 i = auxL_checkinteger(L, 2, 1, INT_MAX) - 1;
6963 } else {
6964 ASN1_OBJECT *obj;
6965
6966 if (!auxS_txt2obj(&obj, luaL_checkstring(L, 2))) {
6967 goto error;
6968 } else if (!obj) {
6969 goto undef;
6970 }
6971
6972 i = X509_CRL_get_ext_by_OBJ(crl, obj, -1);
6973
6974 ASN1_OBJECT_free(obj);
6975 }
6976
6977 ud = prepsimple(L, X509_EXT_CLASS);
6978
6979 if (i < 0 || !(ext = X509_CRL_get0_ext(crl, i)))
6980 goto undef;
6981
6982 if (!(*ud = X509_EXTENSION_dup(ext)))
6983 goto error;
6984
6985 return 1;
6986undef:
6987 return 0;
6988error:
6989 return auxL_error(L, auxL_EOPENSSL, "x509.crl:getExtension");
6990} /* xx_getExtension() */
6991
6992
6993static int xx_getExtensionCount(lua_State *L) {
6994 auxL_pushinteger(L, X509_CRL_get_ext_count(checksimple(L, 1, X509_CRL_CLASS)));
6995
6996 return 1;
6997} /* xx_getExtensionCount() */
6998
6999
7000static int xx_sign(lua_State *L) {
7001 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
7002 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
7003
7004 if (!X509_CRL_sign(crl, key, auxL_optdigest(L, 3, key, NULL)))
7005 return auxL_error(L, auxL_EOPENSSL, "x509.crl:sign");
7006
7007 lua_pushboolean(L, 1);
7008
7009 return 1;
7010} /* xx_sign() */
7011
7012
7013static int xx_verify(lua_State *L) {
7014 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
7015 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
7016
7017 if (!X509_CRL_verify(crl, key))
7018 return auxL_error(L, auxL_EOPENSSL, "x509.crl:verify");
7019
7020 lua_pushboolean(L, 1);
7021
7022 return 1;
7023} /* xx_verify() */
7024
7025
7026static int xx_text(lua_State *L) {
7027 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
7028
7029 BIO *bio = getbio(L);
7030 char *data;
7031 long len;
7032
7033 if (!X509_CRL_print(bio, crl))
7034 return auxL_error(L, auxL_EOPENSSL, "x509.crl:text");
7035
7036 len = BIO_get_mem_data(bio, &data);
7037
7038 lua_pushlstring(L, data, len);
7039
7040 return 1;
7041} /* xx_text() */
7042
7043
7044static int xx__tostring(lua_State *L) {
7045 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
7046 int type = optencoding(L, 2, "pem", X509_PEM|X509_DER);
7047 BIO *bio = getbio(L);
7048 char *data;
7049 long len;
7050
7051 switch (type) {
7052 case X509_PEM:
7053 if (!PEM_write_bio_X509_CRL(bio, crl))
7054 return auxL_error(L, auxL_EOPENSSL, "x509.crl:__tostring");
7055 break;
7056 case X509_DER:
7057 if (!i2d_X509_CRL_bio(bio, crl))
7058 return auxL_error(L, auxL_EOPENSSL, "x509.crl:__tostring");
7059 break;
7060 } /* switch() */
7061
7062 len = BIO_get_mem_data(bio, &data);
7063
7064 lua_pushlstring(L, data, len);
7065
7066 return 1;
7067} /* xx__tostring() */
7068
7069
7070static int xx__gc(lua_State *L) {
7071 X509_CRL **ud = luaL_checkudata(L, 1, X509_CRL_CLASS);
7072
7073 if (*ud) {
7074 X509_CRL_free(*ud);
7075 *ud = NULL;
7076 }
7077
7078 return 0;
7079} /* xx__gc() */
7080
7081static const auxL_Reg xx_methods[] = {
7082 { "getVersion", &xx_getVersion },
7083 { "setVersion", &xx_setVersion },
7084 { "getLastUpdate", &xx_getLastUpdate },
7085 { "setLastUpdate", &xx_setLastUpdate },
7086 { "getNextUpdate", &xx_getNextUpdate },
7087 { "setNextUpdate", &xx_setNextUpdate },
7088 { "getIssuer", &xx_getIssuer },
7089 { "setIssuer", &xx_setIssuer },
7090 { "add", &xx_add },
7091 { "addExtension", &xx_addExtension },
7092 { "getExtension", &xx_getExtension },
7093 { "getExtensionCount", &xx_getExtensionCount },
7094 { "sign", &xx_sign },
7095 { "verify", &xx_verify },
7096 { "text", &xx_text },
7097 { "tostring", &xx__tostring },
7098 { NULL, NULL },
7099};
7100
7101static const auxL_Reg xx_metatable[] = {
7102 { "__tostring", &xx__tostring },
7103 { "__gc", &xx__gc },
7104 { NULL, NULL },
7105};
7106
7107
7108static const auxL_Reg xx_globals[] = {
7109 { "new", &xx_new },
7110 { "interpose", &xx_interpose },
7111 { NULL, NULL },
7112};
7113
7114int luaopen__openssl_x509_crl(lua_State *L) {
7115 initall(L);
7116
7117 auxL_newlib(L, xx_globals, 0);
7118
7119 return 1;
7120} /* luaopen__openssl_x509_crl() */
7121
7122
7123/*
7124 * STACK_OF(X509) - openssl.x509.chain
7125 *
7126 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7127
7128static void xl_dup(lua_State *L, STACK_OF(X509) *src, _Bool copy) {
7129 STACK_OF(X509) **dst = prepsimple(L, X509_CHAIN_CLASS);
7130 X509 *crt;
7131 int i, n;
7132
7133 if (copy) {
7134 if (!(*dst = sk_X509_new_null()))
7135 goto error;
7136
7137 n = sk_X509_num(src);
7138
7139 for (i = 0; i < n; i++) {
7140 if (!(crt = sk_X509_value(src, i)))
7141 continue;
7142
7143 if (!(crt = X509_dup(crt)))
7144 goto error;
7145
7146 if (!sk_X509_push(*dst, crt)) {
7147 X509_free(crt);
7148 goto error;
7149 }
7150 }
7151 } else {
7152 if (!(*dst = sk_X509_dup(src)))
7153 goto error;
7154
7155 n = sk_X509_num(*dst);
7156
7157 for (i = 0; i < n; i++) {
7158 if (!(crt = sk_X509_value(*dst, i)))
7159 continue;
7160 X509_up_ref(crt);
7161 }
7162 }
7163
7164 return;
7165error:
7166 auxL_error(L, auxL_EOPENSSL, "sk_X509_dup");
7167} /* xl_dup() */
7168
7169
7170static int xl_new(lua_State *L) {
7171 STACK_OF(X509) **chain = prepsimple(L, X509_CHAIN_CLASS);
7172
7173 if (!(*chain = sk_X509_new_null()))
7174 return auxL_error(L, auxL_EOPENSSL, "x509.chain.new");
7175
7176 return 1;
7177} /* xl_new() */
7178
7179
7180static int xl_interpose(lua_State *L) {
7181 return interpose(L, X509_CHAIN_CLASS);
7182} /* xl_interpose() */
7183
7184
7185static int xl_add(lua_State *L) {
7186 STACK_OF(X509) *chain = checksimple(L, 1, X509_CHAIN_CLASS);
7187 X509 *crt = checksimple(L, 2, X509_CERT_CLASS);
7188 X509 *dup;
7189
7190 if (!(dup = X509_dup(crt)))
7191 return auxL_error(L, auxL_EOPENSSL, "x509.chain:add");
7192
7193 if (!sk_X509_push(chain, dup)) {
7194 X509_free(dup);
7195 return auxL_error(L, auxL_EOPENSSL, "x509.chain:add");
7196 }
7197
7198 lua_pushvalue(L, 1);
7199
7200 return 1;
7201} /* xl_add() */
7202
7203
7204static int xl__next(lua_State *L) {
7205 STACK_OF(X509) *chain = checksimple(L, lua_upvalueindex(1), X509_CHAIN_CLASS);
7206 int i = lua_tointeger(L, lua_upvalueindex(2));
7207 int n = sk_X509_num(chain);
7208
7209 lua_settop(L, 0);
7210
7211 while (i < n) {
7212 X509 *crt, **ret;
7213
7214 if (!(crt = sk_X509_value(chain, i++)))
7215 continue;
7216
7217 lua_pushinteger(L, i);
7218
7219 ret = prepsimple(L, X509_CERT_CLASS);
7220
7221 if (!(*ret = X509_dup(crt)))
7222 return auxL_error(L, auxL_EOPENSSL, "x509.chain:__next");
7223
7224 break;
7225 }
7226
7227 lua_pushinteger(L, i);
7228 lua_replace(L, lua_upvalueindex(2));
7229
7230 return lua_gettop(L);
7231} /* xl__next() */
7232
7233static int xl__pairs(lua_State *L) {
7234 lua_settop(L, 1);
7235 lua_pushinteger(L, 0);
7236 lua_pushcclosure(L, &xl__next, 2);
7237
7238 return 1;
7239} /* xl__pairs() */
7240
7241
7242static int xl__gc(lua_State *L) {
7243 STACK_OF(X509) **chain = luaL_checkudata(L, 1, X509_CHAIN_CLASS);
7244
7245 if (*chain) {
7246 sk_X509_pop_free(*chain, X509_free);
7247 *chain = NULL;
7248 }
7249
7250 return 0;
7251} /* xl__gc() */
7252
7253
7254static const auxL_Reg xl_methods[] = {
7255 { "add", &xl_add },
7256 { NULL, NULL },
7257};
7258
7259static const auxL_Reg xl_metatable[] = {
7260 { "__pairs", &xl__pairs },
7261 { "__ipairs", &xl__pairs },
7262 { "__gc", &xl__gc },
7263 { NULL, NULL },
7264};
7265
7266static const auxL_Reg xl_globals[] = {
7267 { "new", &xl_new },
7268 { "interpose", &xl_interpose },
7269 { NULL, NULL },
7270};
7271
7272int luaopen__openssl_x509_chain(lua_State *L) {
7273 initall(L);
7274
7275 auxL_newlib(L, xl_globals, 0);
7276
7277 return 1;
7278} /* luaopen__openssl_x509_chain() */
7279
7280
7281/*
7282 * X509_STORE - openssl.x509.store
7283 *
7284 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7285
7286static int xs_new(lua_State *L) {
7287 X509_STORE **ud = prepsimple(L, X509_STORE_CLASS);
7288
7289 if (!(*ud = X509_STORE_new()))
7290 return auxL_error(L, auxL_EOPENSSL, "x509.store");
7291
7292 return 1;
7293} /* xs_new() */
7294
7295
7296static X509_STORE *xs_push(lua_State *L, X509_STORE *store) {
7297 X509_STORE **ud = prepsimple(L, X509_STORE_CLASS);
7298
7299 X509_STORE_up_ref(store);
7300 *ud = store;
7301
7302 return *ud;
7303} /* xs_push() */
7304
7305
7306static int xs_interpose(lua_State *L) {
7307 return interpose(L, X509_STORE_CLASS);
7308} /* xs_interpose() */
7309
7310
7311static int xs_add(lua_State *L) {
7312 X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS);
7313 int i, top = lua_gettop(L);
7314 X509 *crt, *crt_dup;
7315 X509_CRL *crl, *crl_dup;
7316
7317 for (i = 2; i <= top; i++) {
7318 if ((crt = testsimple(L, i, X509_CERT_CLASS))) {
7319 if (!(crt_dup = X509_dup(crt)))
7320 return auxL_error(L, auxL_EOPENSSL, "x509.store:add");
7321
7322 if (!X509_STORE_add_cert(store, crt_dup)) {
7323 X509_free(crt_dup);
7324 return auxL_error(L, auxL_EOPENSSL, "x509.store:add");
7325 }
7326 } else if ((crl = testsimple(L, i, X509_CRL_CLASS))) {
7327 if (!(crl_dup = X509_CRL_dup(crl)))
7328 return auxL_error(L, auxL_EOPENSSL, "x509.store:add");
7329
7330 if (!X509_STORE_add_crl(store, crl_dup)) {
7331 X509_CRL_free(crl_dup);
7332 return auxL_error(L, auxL_EOPENSSL, "x509.store:add");
7333 }
7334 } else {
7335 const char *path = luaL_checkstring(L, i);
7336 struct stat st;
7337 int ok;
7338
7339 if (0 != stat(path, &st))
7340 return luaL_error(L, "%s: %s", path, aux_strerror(errno));
7341
7342 if (S_ISDIR(st.st_mode))
7343 ok = X509_STORE_load_locations(store, NULL, path);
7344 else
7345 ok = X509_STORE_load_locations(store, path, NULL);
7346
7347 if (!ok)
7348 return auxL_error(L, auxL_EOPENSSL, "x509.store:add");
7349 }
7350 }
7351
7352 lua_pushvalue(L, 1);
7353
7354 return 1;
7355} /* xs_add() */
7356
7357
7358static int xs_addDefaults(lua_State *L) {
7359 X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS);
7360
7361 if (!X509_STORE_set_default_paths(store))
7362 return auxL_error(L, auxL_EOPENSSL, "x509.store:addDefaults");
7363
7364 lua_pushvalue(L, 1);
7365
7366 return 1;
7367} /* xs_addDefaults() */
7368
7369
7370static int xs_verify(lua_State *L) {
7371 X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS);
7372 X509 *crt = checksimple(L, 2, X509_CERT_CLASS);
7373 STACK_OF(X509) *chain = NULL, **proof;
7374 X509_STORE_CTX *ctx = NULL;
7375 int ok, why;
7376
7377 /* pre-allocate space for a successful return */
7378 lua_settop(L, 3);
7379 proof = prepsimple(L, X509_CHAIN_CLASS);
7380
7381 if (!lua_isnoneornil(L, 3)) {
7382 X509 *elm;
7383 int i, n;
7384
7385 if (!(chain = sk_X509_dup(checksimple(L, 3, X509_CHAIN_CLASS))))
7386 goto eossl;
7387
7388 n = sk_X509_num(chain);
7389
7390 for (i = 0; i < n; i++) {
7391 if (!(elm = sk_X509_value(chain, i)))
7392 continue;
7393 X509_up_ref(elm);
7394 }
7395 }
7396
7397 if (!(ctx = X509_STORE_CTX_new()) || !X509_STORE_CTX_init(ctx, store, crt, chain)) {
7398 sk_X509_pop_free(chain, X509_free);
7399 goto eossl;
7400 }
7401
7402 ERR_clear_error();
7403
7404 ok = X509_verify_cert(ctx);
7405
7406 switch (ok) {
7407 case 1: /* verified */
7408 if (!(*proof = X509_STORE_CTX_get1_chain(ctx)))
7409 goto eossl;
7410 X509_STORE_CTX_free(ctx);
7411
7412 lua_pushboolean(L, 1);
7413 lua_pushvalue(L, -2);
7414
7415 return 2;
7416 case 0: /* not verified */
7417 why = X509_STORE_CTX_get_error(ctx);
7418 X509_STORE_CTX_free(ctx);
7419
7420 lua_pushboolean(L, 0);
7421 lua_pushstring(L, X509_verify_cert_error_string(why));
7422
7423 return 2;
7424 default:
7425 goto eossl;
7426 }
7427
7428eossl:
7429 if (ctx)
7430 X509_STORE_CTX_free(ctx);
7431
7432 return auxL_error(L, auxL_EOPENSSL, "x509.store:verify");
7433} /* xs_verify() */
7434
7435
7436static int xs__gc(lua_State *L) {
7437 X509_STORE **ud = luaL_checkudata(L, 1, X509_STORE_CLASS);
7438
7439 if (*ud) {
7440 X509_STORE_free(*ud);
7441 *ud = NULL;
7442 }
7443
7444 return 0;
7445} /* xs__gc() */
7446
7447
7448static const auxL_Reg xs_methods[] = {
7449 { "add", &xs_add },
7450 { "addDefaults", &xs_addDefaults },
7451 { "verify", &xs_verify },
7452 { NULL, NULL },
7453};
7454
7455static const auxL_Reg xs_metatable[] = {
7456 { "__gc", &xs__gc },
7457 { NULL, NULL },
7458};
7459
7460static const auxL_Reg xs_globals[] = {
7461 { "new", &xs_new },
7462 { "interpose", &xs_interpose },
7463 { NULL, NULL },
7464};
7465
7466int luaopen__openssl_x509_store(lua_State *L) {
7467 initall(L);
7468
7469 auxL_newlib(L, xs_globals, 0);
7470
7471 lua_pushstring(L, X509_get_default_cert_dir());
7472 lua_setfield(L, -2, "CERT_DIR");
7473 lua_pushstring(L, X509_get_default_cert_file());
7474 lua_setfield(L, -2, "CERT_FILE");
7475 lua_pushstring(L, X509_get_default_cert_dir_env());
7476 lua_setfield(L, -2, "CERT_DIR_EVP");
7477 lua_pushstring(L, X509_get_default_cert_file_env());
7478 lua_setfield(L, -2, "CERT_FILE_EVP");
7479
7480 return 1;
7481} /* luaopen__openssl_x509_store() */
7482
7483
7484/*
7485 * X509_STORE_CTX - openssl.x509.store.context
7486 *
7487 * This object is intended to be a temporary container in OpenSSL, so the
7488 * memory management is quite clumsy. In particular, it doesn't take
7489 * ownership of the X509_STORE object, which means the reference must be
7490 * held externally for the life of the X509_STORE_CTX object.
7491 *
7492 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7493#if 0
7494static int stx_new(lua_State *L) {
7495 X509_STORE_CTX **ud = prepsimple(L, X509_STCTX_CLASS);
7496 STACK_OF(X509) *chain;
7497
7498 if (!(*ud = X509_STORE_CTX_new()))
7499 return auxL_error(L, auxL_EOPENSSL, "x509.store.context");
7500
7501 return 1;
7502} /* stx_new() */
7503
7504
7505static int stx_interpose(lua_State *L) {
7506 return interpose(L, X509_STCTX_CLASS);
7507} /* stx_interpose() */
7508
7509
7510static int stx_add(lua_State *L) {
7511 X509_STORE_CTX *ctx = checksimple(L, 1, X509_STCTX_CLASS);
7512
7513 return 0;
7514} /* stx_add() */
7515
7516
7517static int stx__gc(lua_State *L) {
7518 X509_STORE **ud = luaL_checkudata(L, 1, X509_STORE_CLASS);
7519
7520 if (*ud) {
7521 X509_STORE_free(*ud);
7522 *ud = NULL;
7523 }
7524
7525 return 0;
7526} /* stx__gc() */
7527
7528
7529static const auxL_Reg stx_methods[] = {
7530 { "add", &stx_add },
7531 { NULL, NULL },
7532};
7533
7534static const auxL_Reg stx_metatable[] = {
7535 { "__gc", &stx__gc },
7536 { NULL, NULL },
7537};
7538
7539static const auxL_Reg stx_globals[] = {
7540 { "new", &stx_new },
7541 { "interpose", &stx_interpose },
7542 { NULL, NULL },
7543};
7544
7545int luaopen__openssl_x509_store_context(lua_State *L) {
7546 initall(L);
7547
7548 auxL_newlib(L, stx_globals, 0);
7549
7550 return 1;
7551} /* luaopen__openssl_x509_store_context() */
7552#endif
7553
7554
7555/*
7556 * PKCS12 - openssl.pkcs12
7557 *
7558 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7559
7560static int p12_new(lua_State *L) {
7561 char *pass = NULL;
7562 loadfield(L, 1, "password", LUA_TSTRING, &pass);
7563
7564 EVP_PKEY *key = loadfield_udata(L, 1, "key", PKEY_CLASS);
7565 STACK_OF(X509) *certs = loadfield_udata(L, 1, "certs", X509_CHAIN_CLASS);
7566
7567 PKCS12 **ud = prepsimple(L, PKCS12_CLASS);
7568
7569 int i;
7570 int no_kcert = 0;
7571 X509 *cert = NULL;
7572 X509 *kcert = NULL;
7573 STACK_OF(X509) *ca;
7574
7575 if (!(ca = sk_X509_new_null()))
7576 goto error;
7577
7578 for (i = 0; i < sk_X509_num(certs); i++) {
7579 cert = sk_X509_value(certs, i);
7580 if (key && X509_check_private_key(cert, key)) {
7581 if (!(kcert = X509_dup(cert)))
7582 goto error;
7583 X509_keyid_set1(kcert, NULL, 0);
7584 X509_alias_set1(kcert, NULL, 0);
7585 }
7586 else sk_X509_push(ca, cert);
7587 }
7588 if (key && !kcert) {
7589 no_kcert = 1;
7590 goto error;
7591 }
7592
7593 if (!(*ud = PKCS12_create(pass, NULL, key, kcert, ca, 0, 0, 0, 0, 0)))
7594 goto error;
7595
7596 if (kcert)
7597 X509_free(kcert);
7598 sk_X509_free(ca);
7599
7600 return 1;
7601
7602error:
7603 if (kcert)
7604 X509_free(kcert);
7605 if (ca)
7606 sk_X509_free(ca);
7607
7608 if (no_kcert)
7609 luaL_argerror(L, 1, lua_pushfstring(L, "certificate matching the key not found"));
7610
7611 return auxL_error(L, auxL_EOPENSSL, "pkcs12.new");
7612} /* p12_new() */
7613
7614
7615static int p12_interpose(lua_State *L) {
7616 return interpose(L, PKCS12_CLASS);
7617} /* p12_interpose() */
7618
7619
7620static int p12_parse(lua_State *L) {
7621 /* parse a p12 binary string and return the parts */
7622 PKCS12 *p12;
7623
7624 /* gather input parameters */
7625 size_t len;
7626 const char *blob = luaL_checklstring(L, 1, &len);
7627 const char *passphrase = luaL_optstring(L, 2, NULL);
7628
7629 /* prepare return values */
7630 EVP_PKEY **ud_pkey = prepsimple(L, PKEY_CLASS);
7631 X509 **ud_cert = prepsimple(L, X509_CERT_CLASS);
7632 STACK_OF(X509) **ud_chain = prepsimple(L, X509_CHAIN_CLASS);
7633 /* Note: *ud_chain must be initialised to NULL, which prepsimple does. */
7634
7635 /* read PKCS#12 data into OpenSSL memory buffer */
7636 BIO *bio = BIO_new_mem_buf((void*)blob, len);
7637 if (!bio)
7638 return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse");
7639 p12 = d2i_PKCS12_bio(bio, NULL);
7640 BIO_free(bio);
7641 if (!p12)
7642 return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse");
7643
7644 /* the p12 pointer holds the data we're interested in */
7645 int rc = PKCS12_parse(p12, passphrase, ud_pkey, ud_cert, ud_chain);
7646 PKCS12_free(p12);
7647 if (!rc)
7648 auxL_error(L, auxL_EOPENSSL, "pkcs12.parse");
7649
7650 /* replace the return values by nil if the ud pointers are NULL */
7651 if (*ud_pkey == NULL) {
7652 lua_pushnil(L);
7653 lua_replace(L, -4);
7654 }
7655
7656 if (*ud_cert == NULL) {
7657 lua_pushnil(L);
7658 lua_replace(L, -3);
7659 }
7660
7661 /* other certificates (a chain, STACK_OF(X509) *) */
7662 if (*ud_chain == NULL) {
7663 lua_pop(L, 1);
7664 lua_pushnil(L);
7665 }
7666
7667 return 3;
7668} /* p12_parse() */
7669
7670
7671static int p12__tostring(lua_State *L) {
7672 PKCS12 *p12 = checksimple(L, 1, PKCS12_CLASS);
7673 BIO *bio = getbio(L);
7674 char *data;
7675 long len;
7676
7677 if (!i2d_PKCS12_bio(bio, p12))
7678 return auxL_error(L, auxL_EOPENSSL, "pkcs12:__tostring");
7679
7680 len = BIO_get_mem_data(bio, &data);
7681
7682 lua_pushlstring(L, data, len);
7683
7684 return 1;
7685} /* p12__tostring() */
7686
7687
7688static int p12__gc(lua_State *L) {
7689 PKCS12 **ud = luaL_checkudata(L, 1, PKCS12_CLASS);
7690
7691 if (*ud) {
7692 PKCS12_free(*ud);
7693 *ud = NULL;
7694 }
7695
7696 return 0;
7697} /* p12__gc() */
7698
7699
7700static const auxL_Reg p12_methods[] = {
7701 { "tostring", &p12__tostring },
7702 { NULL, NULL },
7703};
7704
7705static const auxL_Reg p12_metatable[] = {
7706 { "__tostring", &p12__tostring },
7707 { "__gc", &p12__gc },
7708 { NULL, NULL },
7709};
7710
7711static const auxL_Reg p12_globals[] = {
7712 { "new", &p12_new },
7713 { "interpose", &p12_interpose },
7714 { "parse", &p12_parse },
7715 { NULL, NULL },
7716};
7717
7718int luaopen__openssl_pkcs12(lua_State *L) {
7719 initall(L);
7720
7721 auxL_newlib(L, p12_globals, 0);
7722
7723 return 1;
7724} /* luaopen__openssl_pkcs12() */
7725
7726
7727/*
7728 * SSL_CTX - openssl.ssl.context
7729 *
7730 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7731
7732/*
7733 * NOTE: TLS methods and flags were added in tandem. For example, if the
7734 * macro SSL_OP_NO_TLSv1_1 is defined we know TLSv1_1_server_method is also
7735 * declared and defined.
7736 */
7737static int sx_new(lua_State *L) {
7738 static const char *const opts[] = {
7739 [0] = "SSL",
7740 [1] = "TLS",
7741 [2] = "SSLv2",
7742 [3] = "SSLv3",
7743 [4] = "SSLv23",
7744 [5] = "TLSv1", [6] = "TLSv1.0",
7745 [7] = "TLSv1_1", [8] = "TLSv1.1",
7746 [9] = "TLSv1_2", [10] = "TLSv1.2",
7747 [11] = "DTLS",
7748 [12] = "DTLSv1", [13] = "DTLSv1.0",
7749 [14] = "DTLSv1_2", [15] = "DTLSv1.2",
7750 NULL
7751 };
7752 /* later versions of SSL declare a const qualifier on the return type */
7753 __typeof__(&TLSv1_client_method) method = &TLSv1_client_method;
7754 _Bool srv;
7755 SSL_CTX **ud;
7756 int options = 0;
7757
7758 lua_settop(L, 2);
7759 srv = lua_toboolean(L, 2);
7760
7761 switch (auxL_checkoption(L, 1, "TLS", opts, 1)) {
7762 case 0: /* SSL */
7763 method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
7764 options = SSL_OP_NO_SSLv2;
7765 break;
7766 case 1: /* TLS */
7767 method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
7768 options = SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
7769 break;
7770#if HAVE_SSLV2_CLIENT_METHOD && HAVE_SSLV2_SERVER_METHOD
7771 case 2: /* SSLv2 */
7772 method = (srv)? &SSLv2_server_method : &SSLv2_client_method;
7773 break;
7774#endif
7775#ifndef OPENSSL_NO_SSL3
7776 case 3: /* SSLv3 */
7777 method = (srv)? &SSLv3_server_method : &SSLv3_client_method;
7778 break;
7779#endif
7780 case 4: /* SSLv23 */
7781 method = (srv)? &SSLv23_server_method : &SSLv23_client_method;
7782 break;
7783 case 5: /* TLSv1 */
7784 case 6: /* TLSv1.0 */
7785 method = (srv)? &TLSv1_server_method : &TLSv1_client_method;
7786 break;
7787#if defined SSL_OP_NO_TLSv1_1
7788 case 7: /* TLSv1_1 */
7789 case 8: /* TLSv1.1 */
7790 method = (srv)? &TLSv1_1_server_method : &TLSv1_1_client_method;
7791 break;
7792#endif
7793#if defined SSL_OP_NO_TLSv1_2
7794 case 9: /* TLSv1_2 */
7795 case 10: /* TLSv1.2 */
7796 method = (srv)? &TLSv1_2_server_method : &TLSv1_2_client_method;
7797 break;
7798#endif
7799#if HAVE_DTLS_CLIENT_METHOD
7800 case 11: /* DTLS */
7801 method = (srv)? &DTLS_server_method : &DTLS_client_method;
7802 break;
7803#endif
7804#if HAVE_DTLSV1_CLIENT_METHOD
7805 case 12: /* DTLSv1 */
7806 case 13: /* DTLSv1.0 */
7807 method = (srv)? &DTLSv1_server_method : &DTLSv1_client_method;
7808 break;
7809#endif
7810#if HAVE_DTLSV1_2_CLIENT_METHOD
7811 case 14: /* DTLSv1_2 */
7812 case 15: /* DTLSv1.2 */
7813 method = (srv)? &DTLSv1_server_method : &DTLSv1_client_method;
7814 break;
7815#endif
7816 default:
7817 return luaL_argerror(L, 1, "invalid option");
7818 }
7819
7820 ud = prepsimple(L, SSL_CTX_CLASS);
7821
7822 if (!(*ud = SSL_CTX_new(method())))
7823 return auxL_error(L, auxL_EOPENSSL, "ssl.context.new");
7824
7825 SSL_CTX_set_options(*ud, options);
7826
7827 return 1;
7828} /* sx_new() */
7829
7830
7831static int sx_interpose(lua_State *L) {
7832 return interpose(L, SSL_CTX_CLASS);
7833} /* sx_interpose() */
7834
7835
7836static int sx_setOptions(lua_State *L) {
7837 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7838 auxL_Integer options = auxL_checkinteger(L, 2);
7839
7840 auxL_pushinteger(L, SSL_CTX_set_options(ctx, options));
7841
7842 return 1;
7843} /* sx_setOptions() */
7844
7845
7846static int sx_getOptions(lua_State *L) {
7847 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7848
7849 auxL_pushinteger(L, SSL_CTX_get_options(ctx));
7850
7851 return 1;
7852} /* sx_getOptions() */
7853
7854
7855static int sx_clearOptions(lua_State *L) {
7856 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7857 auxL_Integer options = auxL_checkinteger(L, 2);
7858
7859 auxL_pushinteger(L, SSL_CTX_clear_options(ctx, options));
7860
7861 return 1;
7862} /* sx_clearOptions() */
7863
7864
7865static int sx_setStore(lua_State *L) {
7866 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7867 X509_STORE *store = checksimple(L, 2, X509_STORE_CLASS);
7868
7869 SSL_CTX_set1_cert_store(ctx, store);
7870
7871 lua_pushboolean(L, 1);
7872
7873 return 1;
7874} /* sx_setStore() */
7875
7876
7877static int sx_getStore(lua_State *L) {
7878 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7879 X509_STORE *store;
7880
7881 if((store = SSL_CTX_get_cert_store(ctx))) {
7882 xs_push(L, store);
7883 } else {
7884 lua_pushnil(L);
7885 }
7886
7887 return 1;
7888} /* sx_getStore() */
7889
7890
7891static int sx_setParam(lua_State *L) {
7892 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7893 X509_VERIFY_PARAM *xp = checksimple(L, 2, X509_VERIFY_PARAM_CLASS);
7894
7895 if (!SSL_CTX_set1_param(ctx, xp))
7896 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setParam");
7897
7898 lua_pushboolean(L, 1);
7899
7900 return 1;
7901} /* sx_setParam() */
7902
7903
7904static int sx_getParam(lua_State *L) {
7905 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7906 X509_VERIFY_PARAM **ud, *from;
7907
7908 /* X509_VERIFY_PARAM is not refcounted; create a new object and copy into it. */
7909 ud = prepsimple(L, X509_VERIFY_PARAM_CLASS);
7910 if (!(*ud = X509_VERIFY_PARAM_new()))
7911 return auxL_error(L, auxL_EOPENSSL, "ssl.context:getParam");
7912
7913 from = SSL_CTX_get0_param(ctx);
7914
7915 if (!(X509_VERIFY_PARAM_set1(*ud, from)))
7916 /* Note: openssl doesn't set an error as it should for some cases */
7917 return auxL_error(L, auxL_EOPENSSL, "ssl.context:getParam");
7918
7919 return 1;
7920} /* sx_getParam() */
7921
7922
7923static int sx_setVerify(lua_State *L) {
7924 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7925 int mode = luaL_optinteger(L, 2, -1);
7926 int depth = luaL_optinteger(L, 3, -1);
7927
7928 if (mode != -1)
7929 SSL_CTX_set_verify(ctx, mode, 0);
7930
7931 if (depth != -1)
7932 SSL_CTX_set_verify_depth(ctx, depth);
7933
7934 lua_pushboolean(L, 1);
7935
7936 return 1;
7937} /* sx_setVerify() */
7938
7939
7940static int sx_getVerify(lua_State *L) {
7941 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7942
7943 lua_pushinteger(L, SSL_CTX_get_verify_mode(ctx));
7944 lua_pushinteger(L, SSL_CTX_get_verify_depth(ctx));
7945
7946 return 2;
7947} /* sx_getVerify() */
7948
7949
7950static int sx_setCertificate(lua_State *L) {
7951 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7952 X509 *crt = X509_dup(checksimple(L, 2, X509_CERT_CLASS));
7953 int ok;
7954
7955 ok = SSL_CTX_use_certificate(ctx, crt);
7956 X509_free(crt);
7957
7958 if (!ok)
7959 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setCertificate");
7960
7961 lua_pushboolean(L, 1);
7962
7963 return 1;
7964} /* sx_setCertificate() */
7965
7966
7967static int sx_setPrivateKey(lua_State *L) {
7968 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7969 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
7970
7971 /*
7972 * NOTE: No easy way to dup the key, but a shared reference should
7973 * be okay as keys are less mutable than certificates.
7974 *
7975 * FIXME: SSL_CTX_use_PrivateKey will return true even if the
7976 * EVP_PKEY object has no private key. Instead, we'll just get a
7977 * segfault during the SSL handshake. We need to check that a
7978 * private key is actually defined in the object.
7979 */
7980 if (!SSL_CTX_use_PrivateKey(ctx, key))
7981 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setPrivateKey");
7982
7983 lua_pushboolean(L, 1);
7984
7985 return 1;
7986} /* sx_setPrivateKey() */
7987
7988
7989static int sx_setCipherList(lua_State *L) {
7990 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
7991 const char *ciphers = luaL_checkstring(L, 2);
7992
7993 if (!SSL_CTX_set_cipher_list(ctx, ciphers))
7994 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setCipherList");
7995
7996 lua_pushboolean(L, 1);
7997
7998 return 1;
7999} /* sx_setCipherList() */
8000
8001
8002static int sx_setEphemeralKey(lua_State *L) {
8003 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
8004 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
8005 void *tmp;
8006
8007 /*
8008 * NOTE: SSL_CTX_set_tmp duplicates the keys, so we don't need to
8009 * worry about lifetimes. EVP_PKEY_get0 doesn't increment the
8010 * reference count.
8011 */
8012 switch (EVP_PKEY_base_id(key)) {
8013 case EVP_PKEY_RSA:
8014 if (!(tmp = EVP_PKEY_get0(key)))
8015 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setEphemeralKey");
8016
8017 if (!SSL_CTX_set_tmp_rsa(ctx, tmp))
8018 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setEphemeralKey");
8019
8020 break;
8021 case EVP_PKEY_DH:
8022 if (!(tmp = EVP_PKEY_get0(key)))
8023 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setEphemeralKey");
8024
8025 if (!SSL_CTX_set_tmp_dh(ctx, tmp))
8026 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setEphemeralKey");
8027
8028 break;
8029 case EVP_PKEY_EC:
8030 if (!(tmp = EVP_PKEY_get0(key)))
8031 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setEphemeralKey");
8032
8033 if (!SSL_CTX_set_tmp_ecdh(ctx, tmp))
8034 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setEphemeralKey");
8035
8036 break;
8037 default:
8038 return luaL_error(L, "%d: unsupported EVP base type", EVP_PKEY_base_id(key));
8039 } /* switch() */
8040
8041 lua_pushboolean(L, 1);
8042
8043 return 1;
8044} /* sx_setEphemeralKey() */
8045
8046
8047#if HAVE_SSL_CTX_SET_ALPN_PROTOS
8048static int sx_setAlpnProtos(lua_State *L) {
8049 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
8050 luaL_Buffer B;
8051 size_t len;
8052 const char *tmp;
8053
8054 luaL_buffinit(L, &B);
8055 checkprotos(&B, L, 2);
8056 luaL_pushresult(&B);
8057 tmp = lua_tolstring(L, -1, &len);
8058
8059 /* OpenSSL 1.0.2 doesn't update the error stack on failure. */
8060 ERR_clear_error();
8061 if (0 != SSL_CTX_set_alpn_protos(ctx, (const unsigned char*)tmp, len)) {
8062 if (!ERR_peek_error()) {
8063 return luaL_error(L, "unable to set ALPN protocols: %s", aux_strerror(ENOMEM));
8064 } else {
8065 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setAlpnProtos");
8066 }
8067 }
8068
8069 lua_pushboolean(L, 1);
8070
8071 return 1;
8072} /* sx_setAlpnProtos() */
8073#endif
8074
8075
8076#if HAVE_SSL_CTX_SET_ALPN_SELECT_CB
8077static int sx_setAlpnSelect_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *_ctx) {
8078 SSL_CTX *ctx = _ctx;
8079 lua_State *L = NULL;
8080 size_t n, protolen, tmpsiz;
8081 int otop, status;
8082 const void *proto;
8083 void *tmpbuf;
8084
8085 *out = NULL;
8086 *outlen = 0;
8087
8088 /* expect at least two values: return buffer and closure */
8089 if ((n = ex_getdata(&L, EX_SSL_CTX_ALPN_SELECT_CB, ctx)) < 2)
8090 return SSL_TLSEXT_ERR_ALERT_FATAL;
8091
8092 otop = lua_gettop(L) - n;
8093
8094 /* pass SSL object as 1st argument */
8095 if (ssl_pushsafe(L, ssl))
8096 goto fatal;
8097 lua_insert(L, otop + 3);
8098
8099 /* TODO: Install temporary panic handler to catch OOM errors */
8100 /* pass table of protocol names as 2nd argument */
8101 pushprotos(L, in, inlen);
8102 lua_insert(L, otop + 4);
8103
8104 if (LUA_OK != (status = lua_pcall(L, 2 + (n - 2), 1, 0)))
8105 goto fatal;
8106
8107 /* did we get a string result? */
8108 if (!(proto = lua_tolstring(L, -1, &protolen)))
8109 goto noack;
8110
8111 /* will it fit in our return buffer? */
8112 if (!(tmpbuf = lua_touserdata(L, otop + 1)))
8113 goto fatal;
8114
8115 tmpsiz = lua_rawlen(L, otop + 1);
8116
8117 if (protolen > tmpsiz)
8118 goto fatal;
8119
8120 memcpy(tmpbuf, proto, protolen);
8121
8122 /*
8123 * NB: Our return buffer is anchored using the luaL_ref API, so even
8124 * once we pop the stack it will remain valid.
8125 */
8126 *out = tmpbuf;
8127 *outlen = protolen;
8128
8129 lua_settop(L, otop);
8130
8131 return SSL_TLSEXT_ERR_OK;
8132fatal:
8133 lua_settop(L, otop);
8134
8135 return SSL_TLSEXT_ERR_ALERT_FATAL;
8136noack:
8137 lua_settop(L, otop);
8138
8139 return SSL_TLSEXT_ERR_NOACK;
8140} /* sx_setAlpnSelect_cb() */
8141
8142static int sx_setAlpnSelect(lua_State *L) {
8143 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
8144 int error;
8145
8146 luaL_checktype(L, 2, LUA_TFUNCTION);
8147
8148 /* allocate space to store the selected protocol in our callback */
8149 lua_newuserdata(L, UCHAR_MAX);
8150 lua_insert(L, 2);
8151
8152 if ((error = ex_setdata(L, EX_SSL_CTX_ALPN_SELECT_CB, ctx, lua_gettop(L) - 1))) {
8153 if (error > 0) {
8154 return luaL_error(L, "unable to set ALPN protocol selection callback: %s", aux_strerror(error));
8155 } else if (error == auxL_EOPENSSL && !ERR_peek_error()) {
8156 return luaL_error(L, "unable to set ALPN protocol selection callback: Unknown internal error");
8157 } else {
8158 return auxL_error(L, error, "ssl.context:setAlpnSelect");
8159 }
8160 }
8161
8162 SSL_CTX_set_alpn_select_cb(ctx, &sx_setAlpnSelect_cb, ctx);
8163
8164 lua_pushboolean(L, 1);
8165
8166 return 1;
8167} /* sx_setAlpnSelect() */
8168#endif
8169
8170
8171#if HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK
8172static int sx_setHostNameCallback_cb(SSL *ssl, int *ad, void *_ctx) {
8173 SSL_CTX *ctx = _ctx;
8174 lua_State *L = NULL;
8175 size_t n;
8176 int otop, status, ret = SSL_TLSEXT_ERR_ALERT_FATAL;
8177
8178 *ad = SSL_AD_INTERNAL_ERROR;
8179
8180 /* expect at least one value: closure */
8181 if ((n = ex_getdata(&L, EX_SSL_CTX_TLSEXT_SERVERNAME_CB, ctx)) < 1)
8182 return SSL_TLSEXT_ERR_ALERT_FATAL;
8183
8184 otop = lua_gettop(L) - n;
8185
8186 /* pass SSL object as 1st argument */
8187 if (ssl_pushsafe(L, ssl))
8188 goto done;
8189
8190 lua_insert(L, otop + 2);
8191
8192 if (LUA_OK != (status = lua_pcall(L, 1 + (n - 1), 2, 0)))
8193 goto done;
8194
8195 /* callback should return a boolean for OK/NOACK
8196 * or nil + an integer for a controlled error
8197 * everything else will be a fatal internal error
8198 */
8199 if (lua_isboolean(L, -2)) {
8200 ret = lua_toboolean(L, -2) ? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK;
8201 } else {
8202 ret = SSL_TLSEXT_ERR_ALERT_FATAL;
8203 if (lua_isnil(L, -2) && lua_isinteger(L, -1))
8204 *ad = lua_tointeger(L, -1);
8205 }
8206
8207done:
8208 lua_settop(L, otop);
8209
8210 return ret;
8211} /* sx_setHostNameCallback_cb() */
8212
8213
8214static int sx_setHostNameCallback(lua_State *L) {
8215 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
8216 int error;
8217
8218 luaL_checktype(L, 2, LUA_TFUNCTION);
8219
8220 if ((error = ex_setdata(L, EX_SSL_CTX_TLSEXT_SERVERNAME_CB, ctx, lua_gettop(L) - 1))) {
8221 if (error > 0) {
8222 return luaL_error(L, "unable to set hostname selection callback: %s", aux_strerror(error));
8223 } else if (error == auxL_EOPENSSL && !ERR_peek_error()) {
8224 return luaL_error(L, "unable to set hostname selection callback: Unknown internal error");
8225 } else {
8226 return auxL_error(L, error, "ssl.context:setHostNameCallback");
8227 }
8228 }
8229 SSL_CTX_set_tlsext_servername_callback(ctx, sx_setHostNameCallback_cb);
8230 SSL_CTX_set_tlsext_servername_arg(ctx, ctx);
8231
8232 lua_pushboolean(L, 1);
8233
8234 return 1;
8235} /* sx_setHostNameCallback() */
8236#endif
8237
8238
8239int TLSEXT_STATUSTYPEs[] = { TLSEXT_STATUSTYPE_ocsp };
8240const char *TLSEXT_STATUSTYPEs_names[] = { "ocsp", NULL };
8241#define checkTLSEXT_STATUSTYPE(L, idx) \
8242 (TLSEXT_STATUSTYPEs[luaL_checkoption((L), (idx), NULL, TLSEXT_STATUSTYPEs_names)])
8243
8244
8245#if HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE
8246static int sx_setTLSextStatusType(lua_State *L) {
8247 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
8248 int type = checkTLSEXT_STATUSTYPE(L, 2);
8249
8250 if(!SSL_CTX_set_tlsext_status_type(ctx, type))
8251 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setTLSextStatusType");
8252
8253 lua_pushboolean(L, 1);
8254
8255 return 1;
8256} /* sx_setTLSextStatusType() */
8257#endif
8258
8259
8260#if HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE
8261static int sx_getTLSextStatusType(lua_State *L) {
8262 SSL_CTX *ctx = checksimple(L, 1, SSL_CLASS);
8263
8264 int type = SSL_CTX_get_tlsext_status_type(ctx);
8265 switch(type) {
8266 case -1:
8267 lua_pushnil(L);
8268 break;
8269 case TLSEXT_STATUSTYPE_ocsp:
8270 lua_pushliteral(L, "ocsp");
8271 break;
8272 default:
8273 luaL_error(L, "unknown TLS extension %d", type);
8274 }
8275
8276 return 1;
8277} /* sx_getTLSextStatusType() */
8278#endif
8279
8280
8281static int sx__gc(lua_State *L) {
8282 SSL_CTX **ud = luaL_checkudata(L, 1, SSL_CTX_CLASS);
8283
8284 if (*ud) {
8285 SSL_CTX_free(*ud);
8286 *ud = NULL;
8287 }
8288
8289 return 0;
8290} /* sx__gc() */
8291
8292
8293static const auxL_Reg sx_methods[] = {
8294 { "setOptions", &sx_setOptions },
8295 { "getOptions", &sx_getOptions },
8296 { "clearOptions", &sx_clearOptions },
8297 { "setStore", &sx_setStore },
8298 { "getStore", &sx_getStore },
8299 { "setParam", &sx_setParam },
8300 { "getParam", &sx_getParam },
8301 { "setVerify", &sx_setVerify },
8302 { "getVerify", &sx_getVerify },
8303 { "setCertificate", &sx_setCertificate },
8304 { "setPrivateKey", &sx_setPrivateKey },
8305 { "setCipherList", &sx_setCipherList },
8306 { "setEphemeralKey", &sx_setEphemeralKey },
8307#if HAVE_SSL_CTX_SET_ALPN_PROTOS
8308 { "setAlpnProtos", &sx_setAlpnProtos },
8309#endif
8310#if HAVE_SSL_CTX_SET_ALPN_SELECT_CB
8311 { "setAlpnSelect", &sx_setAlpnSelect },
8312#endif
8313#if HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK
8314 { "setHostNameCallback", &sx_setHostNameCallback },
8315#endif
8316#if HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE
8317 { "setTLSextStatusType", &sx_setTLSextStatusType },
8318#endif
8319#if HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE
8320 { "getTLSextStatusType", &sx_getTLSextStatusType },
8321#endif
8322 { NULL, NULL },
8323};
8324
8325static const auxL_Reg sx_metatable[] = {
8326 { "__gc", &sx__gc },
8327 { NULL, NULL },
8328};
8329
8330static const auxL_Reg sx_globals[] = {
8331 { "new", &sx_new },
8332 { "interpose", &sx_interpose },
8333 { NULL, NULL },
8334};
8335
8336static const auxL_IntegerReg sx_verify[] = {
8337 { "VERIFY_NONE", SSL_VERIFY_NONE },
8338 { "VERIFY_PEER", SSL_VERIFY_PEER },
8339 { "VERIFY_FAIL_IF_NO_PEER_CERT", SSL_VERIFY_FAIL_IF_NO_PEER_CERT },
8340 { "VERIFY_CLIENT_ONCE", SSL_VERIFY_CLIENT_ONCE },
8341 { NULL, 0 },
8342};
8343
8344static const auxL_IntegerReg sx_option[] = {
8345 { "OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG },
8346 { "OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG },
8347 { "OP_LEGACY_SERVER_CONNECT", SSL_OP_LEGACY_SERVER_CONNECT },
8348 { "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG },
8349 { "OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG },
8350 { "OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER },
8351 { "OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING },
8352 { "OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG },
8353 { "OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG },
8354 { "OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG },
8355#if defined SSL_OP_NO_TLSv1_1
8356 { "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1 },
8357#endif
8358 { "OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS },
8359 { "OP_ALL", SSL_OP_ALL },
8360 { "OP_NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU },
8361 { "OP_COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE },
8362 { "OP_NO_TICKET", SSL_OP_NO_TICKET },
8363 { "OP_CISCO_ANYCONNECT", SSL_OP_CISCO_ANYCONNECT },
8364 { "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION },
8365#if defined SSL_OP_NO_COMPRESSION
8366 { "OP_NO_COMPRESSION", SSL_OP_NO_COMPRESSION },
8367#endif
8368 { "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION },
8369 { "OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE },
8370 { "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE },
8371 { "OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA },
8372 { "OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE },
8373 { "OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG },
8374 { "OP_NO_SSLv2", SSL_OP_NO_SSLv2 },
8375 { "OP_NO_SSLv3", SSL_OP_NO_SSLv3 },
8376 { "OP_NO_TLSv1", SSL_OP_NO_TLSv1 },
8377#if defined SSL_OP_NO_TLSv1_2
8378 { "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2 },
8379#endif
8380 { "OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1 },
8381 { "OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2 },
8382 { "OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG },
8383 { "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG },
8384#if defined SSL_OP_CRYPTOPRO_TLSEXT_BUG
8385 { "OP_CRYPTOPRO_TLSEXT_BUG", SSL_OP_CRYPTOPRO_TLSEXT_BUG },
8386#endif
8387 { NULL, 0 },
8388};
8389
8390int luaopen__openssl_ssl_context(lua_State *L) {
8391 initall(L);
8392
8393 auxL_newlib(L, sx_globals, 0);
8394 auxL_setintegers(L, sx_verify);
8395 auxL_setintegers(L, sx_option);
8396
8397 return 1;
8398} /* luaopen__openssl_ssl_context() */
8399
8400
8401/*
8402 * SSL - openssl.ssl
8403 *
8404 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
8405
8406static SSL *ssl_push(lua_State *L, SSL *ssl) {
8407 SSL **ud = prepsimple(L, SSL_CLASS);
8408
8409 SSL_up_ref(ssl);
8410 *ud = ssl;
8411
8412 return *ud;
8413} /* ssl_push() */
8414
8415static int ssl_new(lua_State *L) {
8416 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
8417 SSL **ud = prepsimple(L, SSL_CLASS);
8418
8419 *ud = SSL_new(ctx);
8420
8421 if (!*ud)
8422 return auxL_error(L, auxL_EOPENSSL, "ssl.new");
8423
8424 return 1;
8425} /* ssl_new() */
8426
8427
8428static int ssl_interpose(lua_State *L) {
8429 return interpose(L, SSL_CLASS);
8430} /* ssl_interpose() */
8431
8432
8433static int ssl_setContext(lua_State *L) {
8434 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8435 SSL_CTX *ctx = checksimple(L, 2, SSL_CTX_CLASS);
8436
8437 if (!SSL_set_SSL_CTX(ssl, ctx))
8438 return auxL_error(L, auxL_EOPENSSL, "ssl.setContext");
8439
8440 lua_pushboolean(L, 1);
8441
8442 return 1;
8443} /* ssl_setContext() */
8444
8445static int ssl_setOptions(lua_State *L) {
8446 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8447 auxL_Integer options = auxL_checkinteger(L, 2);
8448
8449 auxL_pushinteger(L, SSL_set_options(ssl, options));
8450
8451 return 1;
8452} /* ssl_setOptions() */
8453
8454
8455static int ssl_getOptions(lua_State *L) {
8456 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8457
8458 auxL_pushinteger(L, SSL_get_options(ssl));
8459
8460 return 1;
8461} /* ssl_getOptions() */
8462
8463
8464static int ssl_clearOptions(lua_State *L) {
8465 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8466 auxL_Integer options = auxL_checkinteger(L, 2);
8467
8468 auxL_pushinteger(L, SSL_clear_options(ssl, options));
8469
8470 return 1;
8471} /* ssl_clearOptions() */
8472
8473
8474static int ssl_setParam(lua_State *L) {
8475 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8476 X509_VERIFY_PARAM *xp = checksimple(L, 2, X509_VERIFY_PARAM_CLASS);
8477
8478 if (!SSL_set1_param(ssl, xp))
8479 return auxL_error(L, auxL_EOPENSSL, "ssl:setParam");
8480
8481 lua_pushboolean(L, 1);
8482
8483 return 1;
8484} /* ssl_setParam() */
8485
8486
8487static int ssl_getParam(lua_State *L) {
8488 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8489 X509_VERIFY_PARAM **ud, *from;
8490
8491 /* X509_VERIFY_PARAM is not refcounted; create a new object and copy into it. */
8492 ud = prepsimple(L, X509_VERIFY_PARAM_CLASS);
8493 if (!(*ud = X509_VERIFY_PARAM_new()))
8494 return auxL_error(L, auxL_EOPENSSL, "ssl:getParam");
8495
8496 from = SSL_get0_param(ssl);
8497
8498 if (!(X509_VERIFY_PARAM_set1(*ud, from)))
8499 /* Note: openssl doesn't set an error as it should for some cases */
8500 return auxL_error(L, auxL_EOPENSSL, "ssl:getParam");
8501
8502 return 1;
8503} /* ssl_getParam() */
8504
8505
8506static int ssl_setVerify(lua_State *L) {
8507 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8508 int mode = luaL_optinteger(L, 2, -1);
8509 int depth = luaL_optinteger(L, 3, -1);
8510
8511 if (mode != -1)
8512 SSL_set_verify(ssl, mode, 0);
8513
8514 if (depth != -1)
8515 SSL_set_verify_depth(ssl, depth);
8516
8517 lua_pushboolean(L, 1);
8518
8519 return 1;
8520} /* ssl_setVerify() */
8521
8522
8523static int ssl_getVerify(lua_State *L) {
8524 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8525
8526 lua_pushinteger(L, SSL_get_verify_mode(ssl));
8527 lua_pushinteger(L, SSL_get_verify_depth(ssl));
8528
8529 return 2;
8530} /* ssl_getVerify() */
8531
8532
8533static int ssl_getVerifyResult(lua_State *L) {
8534 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8535 long res = SSL_get_verify_result(ssl);
8536 lua_pushinteger(L, res);
8537 lua_pushstring(L, X509_verify_cert_error_string(res));
8538 return 2;
8539} /* ssl_getVerifyResult() */
8540
8541
8542static int ssl_setCertificate(lua_State *L) {
8543 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8544 X509 *crt = X509_dup(checksimple(L, 2, X509_CERT_CLASS));
8545 int ok;
8546
8547 ok = SSL_use_certificate(ssl, crt);
8548 X509_free(crt);
8549
8550 if (!ok)
8551 return auxL_error(L, auxL_EOPENSSL, "ssl:setCertificate");
8552
8553 lua_pushboolean(L, 1);
8554
8555 return 1;
8556} /* ssl_setCertificate() */
8557
8558
8559static int ssl_setPrivateKey(lua_State *L) {
8560 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8561 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
8562 /*
8563 * NOTE: No easy way to dup the key, but a shared reference should
8564 * be okay as keys are less mutable than certificates.
8565 *
8566 * FIXME: SSL_use_PrivateKey will return true even if the
8567 * EVP_PKEY object has no private key. Instead, we'll just get a
8568 * segfault during the SSL handshake. We need to check that a
8569 * private key is actually defined in the object.
8570 */
8571 if (!SSL_use_PrivateKey(ssl, key))
8572 return auxL_error(L, auxL_EOPENSSL, "ssl:setPrivateKey");
8573
8574 lua_pushboolean(L, 1);
8575
8576 return 1;
8577} /* ssl_setPrivateKey() */
8578
8579
8580static int ssl_getPeerCertificate(lua_State *L) {
8581 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8582 X509 **x509 = prepsimple(L, X509_CERT_CLASS);
8583
8584 if (!(*x509 = SSL_get_peer_certificate(ssl)))
8585 return 0;
8586
8587 return 1;
8588} /* ssl_getPeerCertificate() */
8589
8590
8591static int ssl_getPeerChain(lua_State *L) {
8592 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8593 STACK_OF(X509) *chain;
8594
8595 if (!(chain = SSL_get_peer_cert_chain(ssl)))
8596 return 0;
8597
8598 xl_dup(L, chain, 0);
8599
8600 return 1;
8601} /* ssl_getPeerChain() */
8602
8603
8604static int ssl_getCipherInfo(lua_State *L) {
8605 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8606 const SSL_CIPHER *cipher;
8607 char descr[256];
8608
8609 if (!(cipher = SSL_get_current_cipher(ssl)))
8610 return 0;
8611
8612 lua_newtable(L);
8613
8614 lua_pushstring(L, SSL_CIPHER_get_name(cipher));
8615 lua_setfield(L, -2, "name");
8616
8617 lua_pushinteger(L, SSL_CIPHER_get_bits(cipher, 0));
8618 lua_setfield(L, -2, "bits");
8619
8620 lua_pushstring(L, SSL_CIPHER_get_version(cipher));
8621 lua_setfield(L, -2, "version");
8622
8623 lua_pushstring(L, SSL_CIPHER_description(cipher, descr, sizeof descr));
8624 lua_setfield(L, -2, "description");
8625
8626 return 1;
8627} /* ssl_getCipherInfo() */
8628
8629
8630static int ssl_getHostName(lua_State *L) {
8631 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8632 const char *host;
8633
8634 if (!(host = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)))
8635 return 0;
8636
8637 lua_pushstring(L, host);
8638
8639 return 1;
8640} /* ssl_getHostName() */
8641
8642
8643static int ssl_setHostName(lua_State *L) {
8644 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8645 const char *host = luaL_optstring(L, 2, NULL);
8646
8647 if (!SSL_set_tlsext_host_name(ssl, host))
8648 return auxL_error(L, auxL_EOPENSSL, "ssl:setHostName");
8649
8650 lua_pushboolean(L, 1);
8651
8652 return 1;
8653} /* ssl_setHostName() */
8654
8655
8656static int ssl_getVersion(lua_State *L) {
8657 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8658 int format = luaL_checkoption(L, 2, "d", (const char *[]){ "d", ".", "f", NULL });
8659 int version = SSL_version(ssl);
8660 int major, minor;
8661
8662 switch (format) {
8663 case 1: case 2:
8664 major = 0xff & ((version >> 8));
8665 minor = (0xff & version);
8666
8667 luaL_argcheck(L, minor < 10, 2, "unable to convert SSL version to float because minor version >= 10");
8668 lua_pushnumber(L, major + ((double)minor / 10));
8669
8670 break;
8671 default:
8672 lua_pushinteger(L, version);
8673
8674 break;
8675 }
8676
8677 return 1;
8678} /* ssl_getVersion() */
8679
8680
8681static int ssl_getClientRandom(lua_State *L) {
8682 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8683 luaL_Buffer B;
8684 size_t len;
8685 unsigned char *out;
8686
8687 len = SSL_get_client_random(ssl, NULL, 0);
8688#if LUA_VERSION_NUM < 502
8689 if (LUAL_BUFFERSIZE < len)
8690 luaL_error(L, "ssl:getClientRandom: LUAL_BUFFERSIZE(%d) < SSL_get_client_random(ssl, NULL, 0)", (int)LUAL_BUFFERSIZE, (int)len);
8691 luaL_buffinit(L, &B);
8692 out = (unsigned char*)luaL_prepbuffer(&B);
8693 len = SSL_get_client_random(ssl, out, len);
8694 luaL_addsize(&B, len);
8695 luaL_pushresult(&B);
8696#else
8697 out = (unsigned char*)luaL_buffinitsize(L, &B, len);
8698 len = SSL_get_client_random(ssl, out, len);
8699 luaL_pushresultsize(&B, len);
8700#endif
8701
8702 return 1;
8703} /* ssl_getClientRandom() */
8704
8705
8706static int ssl_getClientVersion(lua_State *L) {
8707 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8708 int format = luaL_checkoption(L, 2, "d", (const char *[]){ "d", ".", "f", NULL });
8709 int version = SSL_client_version(ssl);
8710 int major, minor;
8711
8712 switch (format) {
8713 case 1: case 2:
8714 major = 0xff & ((version >> 8));
8715 minor = (0xff & version);
8716
8717 luaL_argcheck(L, minor < 10, 2, "unable to convert SSL client version to float because minor version >= 10");
8718 lua_pushnumber(L, major + ((double)minor / 10));
8719
8720 break;
8721 default:
8722 lua_pushinteger(L, version);
8723
8724 break;
8725 }
8726
8727 return 1;
8728} /* ssl_getClientVersion() */
8729
8730
8731#if HAVE_SSL_GET0_ALPN_SELECTED
8732static int ssl_getAlpnSelected(lua_State *L) {
8733 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8734 const unsigned char *data;
8735 unsigned len;
8736 SSL_get0_alpn_selected(ssl, &data, &len);
8737 if (0 == len) {
8738 lua_pushnil(L);
8739 } else {
8740 lua_pushlstring(L, (const char *)data, len);
8741 }
8742 return 1;
8743} /* ssl_getAlpnSelected() */
8744#endif
8745
8746
8747#if HAVE_SSL_SET_ALPN_PROTOS
8748static int ssl_setAlpnProtos(lua_State *L) {
8749 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8750 luaL_Buffer B;
8751 size_t len;
8752 const char *tmp;
8753
8754 luaL_buffinit(L, &B);
8755 checkprotos(&B, L, 2);
8756 luaL_pushresult(&B);
8757 tmp = lua_tolstring(L, -1, &len);
8758
8759 /* OpenSSL 1.0.2 doesn't update the error stack on failure. */
8760 ERR_clear_error();
8761 if (0 != SSL_set_alpn_protos(ssl, (const unsigned char*)tmp, len)) {
8762 if (!ERR_peek_error()) {
8763 return luaL_error(L, "unable to set ALPN protocols: %s", aux_strerror(ENOMEM));
8764 } else {
8765 return auxL_error(L, auxL_EOPENSSL, "ssl:setAlpnProtos");
8766 }
8767 }
8768
8769 lua_pushboolean(L, 1);
8770
8771 return 1;
8772} /* ssl_setAlpnProtos() */
8773#endif
8774
8775
8776static int ssl_setTLSextStatusType(lua_State *L) {
8777 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8778 int type = checkTLSEXT_STATUSTYPE(L, 2);
8779
8780 if(!SSL_set_tlsext_status_type(ssl, type))
8781 return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusType");
8782
8783 lua_pushboolean(L, 1);
8784
8785 return 1;
8786} /* ssl_setTLSextStatusType() */
8787
8788
8789#if HAVE_SSL_GET_TLSEXT_STATUS_TYPE
8790static int ssl_getTLSextStatusType(lua_State *L) {
8791 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8792
8793 int type = SSL_get_tlsext_status_type(ssl);
8794 switch(type) {
8795 case -1:
8796 lua_pushnil(L);
8797 break;
8798 case TLSEXT_STATUSTYPE_ocsp:
8799 lua_pushliteral(L, "ocsp");
8800 break;
8801 default:
8802 luaL_error(L, "unknown TLS extension %d", type);
8803 }
8804
8805 return 1;
8806} /* ssl_getTLSextStatusType() */
8807#endif
8808
8809
8810static int ssl_setTLSextStatusOCSPResp(lua_State *L) {
8811 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8812 OCSP_RESPONSE *or = testsimple(L, 2, OCSP_RESPONSE_CLASS);
8813
8814 unsigned char *resp = NULL;
8815 long resp_len;
8816
8817 if (or) {
8818 resp_len = i2d_OCSP_RESPONSE(or, &resp);
8819 if (resp_len <= 0)
8820 return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusOCSPResp");
8821 } else {
8822 resp_len = 0;
8823 }
8824
8825 if (!SSL_set_tlsext_status_ocsp_resp(ssl, resp, resp_len))
8826 return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusOCSPResp");
8827
8828 lua_pushboolean(L, 1);
8829
8830 return 1;
8831} /* ssl_setTLSextStatusOCSPResp() */
8832
8833
8834static int ssl_getTLSextStatusOCSPResp(lua_State *L) {
8835 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8836
8837 OCSP_RESPONSE **ud = prepsimple(L, OCSP_RESPONSE_CLASS);
8838 const unsigned char *resp;
8839 long resp_len;
8840
8841 resp_len = SSL_get_tlsext_status_ocsp_resp(ssl, &resp);
8842 if (resp == NULL) {
8843 lua_pushnil(L);
8844 return 1;
8845 }
8846 if (resp_len == -1)
8847 return auxL_error(L, auxL_EOPENSSL, "ssl:getTLSextStatusOCSPResp");
8848
8849 *ud = d2i_OCSP_RESPONSE(NULL, &resp, resp_len);
8850 if(*ud == NULL)
8851 return auxL_error(L, auxL_EOPENSSL, "ssl:getTLSextStatusOCSPResp");
8852
8853 return 1;
8854} /* ssl_getTLSextStatusOCSPResp() */
8855
8856
8857static int ssl__gc(lua_State *L) {
8858 SSL **ud = luaL_checkudata(L, 1, SSL_CLASS);
8859
8860 if (*ud) {
8861 SSL_free(*ud);
8862 *ud = NULL;
8863 }
8864
8865 return 0;
8866} /* ssl__gc() */
8867
8868
8869static const auxL_Reg ssl_methods[] = {
8870 { "setContext", &ssl_setContext },
8871 { "setOptions", &ssl_setOptions },
8872 { "getOptions", &ssl_getOptions },
8873 { "clearOptions", &ssl_clearOptions },
8874 { "setParam", &ssl_setParam },
8875 { "getParam", &ssl_getParam },
8876 { "setVerify", &ssl_setVerify },
8877 { "getVerify", &ssl_getVerify },
8878 { "getVerifyResult", &ssl_getVerifyResult },
8879 { "setCertificate", &ssl_setCertificate },
8880 { "setPrivateKey", &ssl_setPrivateKey },
8881 { "getPeerCertificate", &ssl_getPeerCertificate },
8882 { "getPeerChain", &ssl_getPeerChain },
8883 { "getCipherInfo", &ssl_getCipherInfo },
8884 { "getHostName", &ssl_getHostName },
8885 { "setHostName", &ssl_setHostName },
8886 { "getVersion", &ssl_getVersion },
8887 { "getClientRandom", &ssl_getClientRandom },
8888 { "getClientVersion", &ssl_getClientVersion },
8889#if HAVE_SSL_GET0_ALPN_SELECTED
8890 { "getAlpnSelected", &ssl_getAlpnSelected },
8891#endif
8892#if HAVE_SSL_SET_ALPN_PROTOS
8893 { "setAlpnProtos", &ssl_setAlpnProtos },
8894#endif
8895 { "setTLSextStatusType", &ssl_setTLSextStatusType },
8896#if HAVE_SSL_GET_TLSEXT_STATUS_TYPE
8897 { "getTLSextStatusType", &ssl_getTLSextStatusType },
8898#endif
8899 { "setTLSextStatusOCSPResp", &ssl_setTLSextStatusOCSPResp },
8900 { "getTLSextStatusOCSPResp", &ssl_getTLSextStatusOCSPResp },
8901 { NULL, NULL },
8902};
8903
8904static const auxL_Reg ssl_metatable[] = {
8905 { "__gc", &ssl__gc },
8906 { NULL, NULL },
8907};
8908
8909static const auxL_Reg ssl_globals[] = {
8910 { "new", &ssl_new },
8911 { "interpose", &ssl_interpose },
8912 { NULL, NULL },
8913};
8914
8915static const auxL_IntegerReg ssl_version[] = {
8916 { "SSL2_VERSION", SSL2_VERSION },
8917 { "SSL3_VERSION", SSL3_VERSION },
8918 { "TLS1_VERSION", TLS1_VERSION },
8919#if defined TLS1_1_VERSION
8920 { "TLS1_1_VERSION", TLS1_1_VERSION },
8921#endif
8922#if defined TLS1_2_VERSION
8923 { "TLS1_2_VERSION", TLS1_2_VERSION },
8924#endif
8925 { NULL, 0 },
8926};
8927
8928
8929int luaopen__openssl_ssl(lua_State *L) {
8930 initall(L);
8931
8932 auxL_newlib(L, ssl_globals, 0);
8933 auxL_setintegers(L, ssl_version);
8934 auxL_setintegers(L, sx_verify);
8935 auxL_setintegers(L, sx_option);
8936
8937 return 1;
8938} /* luaopen__openssl_ssl() */
8939
8940
8941/*
8942 * X509_VERIFY_PARAM
8943 *
8944 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
8945
8946static int xp_new(lua_State *L) {
8947 X509_VERIFY_PARAM **ud = prepsimple(L, X509_VERIFY_PARAM_CLASS);
8948
8949 if (!(*ud = X509_VERIFY_PARAM_new()))
8950 return auxL_error(L, auxL_EOPENSSL, "x509.verify_param.new");
8951
8952 return 1;
8953} /* xp_new() */
8954
8955
8956static int xp_interpose(lua_State *L) {
8957 return interpose(L, X509_VERIFY_PARAM_CLASS);
8958} /* xp_interpose() */
8959
8960
8961/*
8962 * NB: Per the OpenSSL source, "[t]he 'inh_flags' field determines how this
8963 * function behaves". (Referring to X509_VERIFY_PARAM_inherit.) The way to
8964 * set inh_flags prior to OpenSSL 1.1 was by OR'ing flags into the inh_flags
8965 * member and restoring it after the call. The OpenSSL 1.1 API makes the
8966 * X509_VERIFY_PARAM object opaque, X509_VERIFY_PARAM_inherit, and there's
8967 * no other function to set the flags argument; therefore it's not possible
8968 * to control the inherit behavior from OpenSSL 1.1.
8969 *
8970 * For more details see
8971 * https://github.com/openssl/openssl/issues/2054 and the original
8972 * https://github.com/wahern/luaossl/pull/76/commits/db6e414d68c0f94c2497d363f6131b4de1710ba9
8973 */
8974static int xp_inherit(lua_State *L) {
8975 X509_VERIFY_PARAM *dest = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
8976 X509_VERIFY_PARAM *src = checksimple(L, 2, X509_VERIFY_PARAM_CLASS);
8977 int ret;
8978
8979 ret = X509_VERIFY_PARAM_inherit(dest, src);
8980 if (!ret)
8981 /* Note: openssl doesn't set an error as it should for some cases */
8982 return auxL_error(L, auxL_EOPENSSL, "x509.verify_param:inherit");
8983
8984 lua_pushboolean(L, 1);
8985 return 1;
8986} /* xp_inherit() */
8987
8988
8989static const X509_PURPOSE *purpose_checktype(lua_State *L, int index) {
8990 const char *purpose_name;
8991 int purpose_id;
8992 int purpose_idx;
8993 const X509_PURPOSE *purpose;
8994
8995 if (lua_isnumber(L, index)) {
8996 purpose_id = luaL_checkinteger(L, index);
8997 purpose_idx = X509_PURPOSE_get_by_id(purpose_id);
8998 if (purpose_idx < 0)
8999 luaL_argerror(L, index, lua_pushfstring(L, "%d: invalid purpose", purpose_id));
9000 } else {
9001 purpose_name = luaL_checkstring(L, index);
9002 purpose_idx = X509_PURPOSE_get_by_sname((char*)purpose_name);
9003 if (purpose_idx < 0)
9004 luaL_argerror(L, index, lua_pushfstring(L, "%s: invalid purpose", purpose_name));
9005 }
9006
9007 purpose = X509_PURPOSE_get0(purpose_idx);
9008 return purpose;
9009} /* purpose_checktype() */
9010
9011
9012static int xp_setPurpose(lua_State *L) {
9013 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9014 const X509_PURPOSE *purpose = purpose_checktype(L, 2);
9015
9016 if (!X509_VERIFY_PARAM_set_purpose(xp, X509_PURPOSE_get_id((X509_PURPOSE*)purpose)))
9017 return auxL_error(L, auxL_EOPENSSL, "x509.verify_param:setPurpose");
9018
9019 lua_pushboolean(L, 1);
9020 return 1;
9021} /* xp_setPurpose() */
9022
9023
9024static int xp_setTime(lua_State *L) {
9025 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9026 time_t t = luaL_checkinteger(L, 2);
9027
9028 X509_VERIFY_PARAM_set_time(xp, t);
9029
9030 lua_pushboolean(L, 1);
9031 return 1;
9032} /* xp_setTime() */
9033
9034
9035static int xp_setDepth(lua_State *L) {
9036 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9037 int depth = luaL_checkinteger(L, 2);
9038
9039 X509_VERIFY_PARAM_set_depth(xp, depth);
9040
9041 lua_pushboolean(L, 1);
9042 return 1;
9043} /* xp_setDepth() */
9044
9045
9046static int xp_getDepth(lua_State *L) {
9047 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9048
9049 int depth = X509_VERIFY_PARAM_get_depth(xp);
9050
9051 lua_pushinteger(L, depth);
9052 return 1;
9053} /* xp_getDepth() */
9054
9055
9056#if HAVE_X509_VERIFY_PARAM_SET_AUTH_LEVEL
9057static int xp_setAuthLevel(lua_State *L) {
9058 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9059 int auth_level = luaL_checkinteger(L, 2);
9060
9061 X509_VERIFY_PARAM_set_auth_level(xp, auth_level);
9062
9063 lua_pushboolean(L, 1);
9064 return 1;
9065} /* xp_setAuthLevel() */
9066
9067
9068static int xp_getAuthLevel(lua_State *L) {
9069 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9070
9071 int auth_level = X509_VERIFY_PARAM_get_auth_level(xp);
9072
9073 lua_pushinteger(L, auth_level);
9074 return 1;
9075} /* xp_getAuthLevel() */
9076#endif
9077
9078
9079#if HAVE_X509_VERIFY_PARAM_SET1_HOST
9080static int xp_setHost(lua_State *L) {
9081 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9082 size_t len;
9083 const char *str = luaL_optlstring(L, 2, NULL, &len); /* NULL = clear hosts */
9084
9085 if (!X509_VERIFY_PARAM_set1_host(xp, str, len))
9086 /* Note: openssl doesn't set an error as it should for some cases */
9087 return auxL_error(L, auxL_EOPENSSL, "x509.verify_param:setHost");
9088
9089 lua_pushboolean(L, 1);
9090 return 1;
9091} /* xp_setHost() */
9092#endif
9093
9094
9095#if HAVE_X509_VERIFY_PARAM_ADD1_HOST
9096static int xp_addHost(lua_State *L) {
9097 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9098 size_t len;
9099 const char *str = luaL_checklstring(L, 2, &len);
9100
9101 if (!X509_VERIFY_PARAM_add1_host(xp, str, len))
9102 /* Note: openssl doesn't set an error as it should for some cases */
9103 return auxL_error(L, auxL_EOPENSSL, "x509.verify_param:addHost");
9104
9105 lua_pushboolean(L, 1);
9106 return 1;
9107} /* xp_addHost() */
9108#endif
9109
9110
9111#if HAVE_X509_VERIFY_PARAM_SET1_EMAIL
9112static int xp_setEmail(lua_State *L) {
9113 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9114 size_t len;
9115 const char *str = luaL_checklstring(L, 2, &len);
9116
9117 if (!X509_VERIFY_PARAM_set1_email(xp, str, len))
9118 /* Note: openssl doesn't set an error as it should for some cases */
9119 return auxL_error(L, auxL_EOPENSSL, "x509.verify_param:setEmail");
9120
9121 lua_pushboolean(L, 1);
9122 return 1;
9123} /* xp_setEmail() */
9124#endif
9125
9126
9127#if HAVE_X509_VERIFY_PARAM_SET1_IP_ASC
9128static int xp_setIP(lua_State *L) {
9129 X509_VERIFY_PARAM *xp = checksimple(L, 1, X509_VERIFY_PARAM_CLASS);
9130 const char *str = luaL_checkstring(L, 2);
9131
9132 if (!X509_VERIFY_PARAM_set1_ip_asc(xp, str))
9133 /* Note: openssl doesn't set an error as it should for some cases */
9134 return auxL_error(L, auxL_EOPENSSL, "x509.verify_param:setIP");
9135
9136 lua_pushboolean(L, 1);
9137 return 1;
9138} /* xp_setIP() */
9139#endif
9140
9141
9142static int xp__gc(lua_State *L) {
9143 X509_VERIFY_PARAM **ud = luaL_checkudata(L, 1, X509_VERIFY_PARAM_CLASS);
9144
9145 X509_VERIFY_PARAM_free(*ud);
9146 *ud = NULL;
9147
9148 return 0;
9149} /* xp__gc() */
9150
9151
9152static const auxL_Reg xp_methods[] = {
9153 { "inherit", &xp_inherit },
9154 { "setPurpose", &xp_setPurpose },
9155 { "setTime", &xp_setTime },
9156 { "setDepth", &xp_setDepth },
9157 { "getDepth", &xp_getDepth },
9158#if HAVE_X509_VERIFY_PARAM_SET_AUTH_LEVEL
9159 { "setAuthLevel", &xp_setAuthLevel },
9160 { "getAuthLevel", &xp_getAuthLevel },
9161#endif
9162#if HAVE_X509_VERIFY_PARAM_SET1_HOST
9163 { "setHost", &xp_setHost },
9164#endif
9165#if HAVE_X509_VERIFY_PARAM_ADD1_HOST
9166 { "addHost", &xp_addHost },
9167#endif
9168#if HAVE_X509_VERIFY_PARAM_SET1_EMAIL
9169 { "setEmail", &xp_setEmail },
9170#endif
9171#if HAVE_X509_VERIFY_PARAM_SET1_IP_ASC
9172 { "setIP", &xp_setIP },
9173#endif
9174 { NULL, NULL },
9175};
9176
9177static const auxL_Reg xp_metatable[] = {
9178 { "__gc", &xp__gc },
9179 { NULL, NULL },
9180};
9181
9182static const auxL_Reg xp_globals[] = {
9183 { "new", &xp_new },
9184 { "interpose", &xp_interpose },
9185 { NULL, NULL },
9186};
9187
9188static const auxL_IntegerReg xp_inherit_flags[] = {
9189 { "DEFAULT", X509_VP_FLAG_DEFAULT },
9190 { "OVERWRITE", X509_VP_FLAG_OVERWRITE },
9191 { "RESET_FLAGS", X509_VP_FLAG_RESET_FLAGS },
9192 { "LOCKED", X509_VP_FLAG_LOCKED },
9193 { "ONCE", X509_VP_FLAG_ONCE },
9194 { NULL, 0 }
9195};
9196
9197int luaopen__openssl_x509_verify_param(lua_State *L) {
9198 initall(L);
9199
9200 auxL_newlib(L, xp_globals, 0);
9201 auxL_setintegers(L, xp_inherit_flags);
9202
9203 return 1;
9204} /* luaopen__openssl_x509_verify_param() */
9205
9206
9207/*
9208 * Digest - openssl.digest
9209 *
9210 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
9211
9212static const EVP_MD *md_optdigest(lua_State *L, int index) {
9213 const char *name = luaL_optstring(L, index, "sha1");
9214 const EVP_MD *type;
9215
9216 if (!(type = EVP_get_digestbyname(name)))
9217 luaL_argerror(L, index, lua_pushfstring(L, "%s: invalid digest type", name));
9218
9219 return type;
9220} /* md_optdigest() */
9221
9222
9223static int md_new(lua_State *L) {
9224 const EVP_MD *type = md_optdigest(L, 1);
9225 EVP_MD_CTX **ctx;
9226
9227 ctx = prepsimple(L, DIGEST_CLASS, NULL);
9228 if (!(*ctx = EVP_MD_CTX_new()) || !EVP_DigestInit_ex(*ctx, type, NULL))
9229 return auxL_error(L, auxL_EOPENSSL, "digest.new");
9230
9231 return 1;
9232} /* md_new() */
9233
9234
9235static int md_interpose(lua_State *L) {
9236 return interpose(L, DIGEST_CLASS);
9237} /* md_interpose() */
9238
9239
9240static void md_update_(lua_State *L, EVP_MD_CTX *ctx, int from, int to) {
9241 int i;
9242
9243 for (i = from; i <= to; i++) {
9244 const void *p;
9245 size_t n;
9246
9247 p = luaL_checklstring(L, i, &n);
9248
9249 if (!EVP_DigestUpdate(ctx, p, n))
9250 auxL_error(L, auxL_EOPENSSL, "digest:update");
9251 }
9252} /* md_update_() */
9253
9254
9255static int md_update(lua_State *L) {
9256 EVP_MD_CTX *ctx = checksimple(L, 1, DIGEST_CLASS);
9257
9258 md_update_(L, ctx, 2, lua_gettop(L));
9259
9260 lua_pushvalue(L, 1);
9261
9262 return 1;
9263} /* md_update() */
9264
9265
9266static int md_final(lua_State *L) {
9267 EVP_MD_CTX *ctx = checksimple(L, 1, DIGEST_CLASS);
9268 unsigned char md[EVP_MAX_MD_SIZE];
9269 unsigned len;
9270
9271 md_update_(L, ctx, 2, lua_gettop(L));
9272
9273 if (!EVP_DigestFinal_ex(ctx, md, &len))
9274 return auxL_error(L, auxL_EOPENSSL, "digest:final");
9275
9276 lua_pushlstring(L, (char *)md, len);
9277
9278 return 1;
9279} /* md_final() */
9280
9281
9282static int md__gc(lua_State *L) {
9283 EVP_MD_CTX **ctx = luaL_checkudata(L, 1, DIGEST_CLASS);
9284
9285 EVP_MD_CTX_free(*ctx);
9286 *ctx = NULL;
9287
9288 return 0;
9289} /* md__gc() */
9290
9291
9292static const auxL_Reg md_methods[] = {
9293 { "update", &md_update },
9294 { "final", &md_final },
9295 { NULL, NULL },
9296};
9297
9298static const auxL_Reg md_metatable[] = {
9299 { "__gc", &md__gc },
9300 { NULL, NULL },
9301};
9302
9303static const auxL_Reg md_globals[] = {
9304 { "new", &md_new },
9305 { "interpose", &md_interpose },
9306 { NULL, NULL },
9307};
9308
9309int luaopen__openssl_digest(lua_State *L) {
9310 initall(L);
9311
9312 auxL_newlib(L, md_globals, 0);
9313
9314 return 1;
9315} /* luaopen__openssl_digest() */
9316
9317
9318/*
9319 * HMAC - openssl.hmac
9320 *
9321 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
9322
9323static int hmac_new(lua_State *L) {
9324 const void *key;
9325 size_t len;
9326 const EVP_MD *type;
9327 HMAC_CTX **ctx;
9328
9329 key = luaL_checklstring(L, 1, &len);
9330 type = md_optdigest(L, 2);
9331
9332 ctx = prepsimple(L, HMAC_CLASS, NULL);
9333 if (!(*ctx = HMAC_CTX_new()))
9334 goto eossl;
9335
9336#if HMAC_INIT_EX_INT
9337 if (!HMAC_Init_ex(*ctx, key, len, type, NULL))
9338 goto eossl;
9339#else
9340 HMAC_Init_ex(*ctx, key, len, type, NULL);
9341#endif
9342
9343 return 1;
9344eossl:
9345 return auxL_error(L, auxL_EOPENSSL, "hmac.new");
9346} /* hmac_new() */
9347
9348
9349static int hmac_interpose(lua_State *L) {
9350 return interpose(L, HMAC_CLASS);
9351} /* hmac_interpose() */
9352
9353
9354static void hmac_update_(lua_State *L, HMAC_CTX *ctx, int from, int to) {
9355 int i;
9356
9357 for (i = from; i <= to; i++) {
9358 const void *p;
9359 size_t n;
9360
9361 p = luaL_checklstring(L, i, &n);
9362
9363 HMAC_Update(ctx, p, n);
9364 }
9365} /* hmac_update_() */
9366
9367
9368static int hmac_update(lua_State *L) {
9369 HMAC_CTX *ctx = checksimple(L, 1, HMAC_CLASS);
9370
9371 hmac_update_(L, ctx, 2, lua_gettop(L));
9372
9373 lua_pushvalue(L, 1);
9374
9375 return 1;
9376} /* hmac_update() */
9377
9378
9379static int hmac_final(lua_State *L) {
9380 HMAC_CTX *ctx = checksimple(L, 1, HMAC_CLASS);
9381 unsigned char hmac[EVP_MAX_MD_SIZE];
9382 unsigned len;
9383
9384 hmac_update_(L, ctx, 2, lua_gettop(L));
9385
9386 HMAC_Final(ctx, hmac, &len);
9387
9388 lua_pushlstring(L, (char *)hmac, len);
9389
9390 return 1;
9391} /* hmac_final() */
9392
9393
9394static int hmac__gc(lua_State *L) {
9395 HMAC_CTX **ctx = luaL_checkudata(L, 1, HMAC_CLASS);
9396
9397 HMAC_CTX_free(*ctx);
9398 *ctx = NULL;
9399
9400 return 0;
9401} /* hmac__gc() */
9402
9403
9404static const auxL_Reg hmac_methods[] = {
9405 { "update", &hmac_update },
9406 { "final", &hmac_final },
9407 { NULL, NULL },
9408};
9409
9410static const auxL_Reg hmac_metatable[] = {
9411 { "__gc", &hmac__gc },
9412 { NULL, NULL },
9413};
9414
9415static const auxL_Reg hmac_globals[] = {
9416 { "new", &hmac_new },
9417 { "interpose", &hmac_interpose },
9418 { NULL, NULL },
9419};
9420
9421int luaopen__openssl_hmac(lua_State *L) {
9422 initall(L);
9423
9424 auxL_newlib(L, hmac_globals, 0);
9425
9426 return 1;
9427} /* luaopen__openssl_hmac() */
9428
9429
9430/*
9431 * Cipher - openssl.cipher
9432 *
9433 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
9434
9435static const EVP_CIPHER *cipher_checktype(lua_State *L, int index) {
9436 const char *name = luaL_checkstring(L, index);
9437 const EVP_CIPHER *type;
9438
9439 if (!(type = EVP_get_cipherbyname(name)))
9440 luaL_argerror(L, index, lua_pushfstring(L, "%s: invalid cipher type", name));
9441
9442 return type;
9443} /* cipher_checktype() */
9444
9445
9446static int cipher_new(lua_State *L) {
9447 const EVP_CIPHER *type;
9448 EVP_CIPHER_CTX **ctx;
9449 unsigned char key[EVP_MAX_KEY_LENGTH] = { 0 };
9450
9451 type = cipher_checktype(L, 1);
9452
9453 ctx = prepsimple(L, CIPHER_CLASS, NULL);
9454 if (!(*ctx = EVP_CIPHER_CTX_new()))
9455 goto eossl;
9456
9457 /*
9458 * NOTE: For some ciphers like AES calling :update or :final without
9459 * setting a key causes a SEGV. Set a dummy key here. Same solution
9460 * as used by Ruby OSSL.
9461 */
9462 if (!EVP_CipherInit_ex(*ctx, type, NULL, key, NULL, -1))
9463 goto eossl;
9464
9465 return 1;
9466eossl:
9467 return auxL_error(L, auxL_EOPENSSL, "cipher.new");
9468} /* cipher_new() */
9469
9470
9471static int cipher_interpose(lua_State *L) {
9472 return interpose(L, CIPHER_CLASS);
9473} /* cipher_interpose() */
9474
9475
9476static int cipher_init(lua_State *L, _Bool encrypt) {
9477 EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
9478 const void *key, *iv;
9479 size_t n, m;
9480
9481 key = luaL_checklstring(L, 2, &n);
9482 m = (size_t)EVP_CIPHER_CTX_key_length(ctx);
9483 luaL_argcheck(L, n == m, 2, lua_pushfstring(L, "%d: invalid key length (should be %d)", (int)n, (int)m));
9484
9485 iv = luaL_optlstring(L, 3, NULL, &n);
9486 m = (size_t)EVP_CIPHER_CTX_iv_length(ctx);
9487 luaL_argcheck(L, n == m, 3, lua_pushfstring(L, "%d: invalid IV length (should be %d)", (int)n, (int)m));
9488
9489 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, encrypt))
9490 goto sslerr;
9491
9492 if (!lua_isnoneornil(L, 4)) {
9493 luaL_checktype(L, 4, LUA_TBOOLEAN);
9494
9495 if (!EVP_CIPHER_CTX_set_padding(ctx, lua_toboolean(L, 4)))
9496 goto sslerr;
9497 }
9498
9499 lua_settop(L, 1);
9500
9501 return 1;
9502sslerr:
9503 return auxL_error(L, auxL_EOPENSSL, (encrypt)? "cipher:encrypt" : "cipher:decrypt");
9504} /* cipher_init() */
9505
9506
9507static int cipher_encrypt(lua_State *L) {
9508 return cipher_init(L, 1);
9509} /* cipher_encrypt() */
9510
9511
9512static int cipher_decrypt(lua_State *L) {
9513 return cipher_init(L, 0);
9514} /* cipher_decrypt() */
9515
9516
9517static _Bool cipher_update_(lua_State *L, EVP_CIPHER_CTX *ctx, luaL_Buffer *B, int from, int to) {
9518 const unsigned char *p, *pe;
9519 size_t block, step, n;
9520 int i;
9521
9522 block = EVP_CIPHER_CTX_block_size(ctx);
9523
9524 if (LUAL_BUFFERSIZE < block * 2)
9525 luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%d) < 2 * EVP_CIPHER_CTX_block_size(%d)", (int)LUAL_BUFFERSIZE, (int)block);
9526
9527 step = LUAL_BUFFERSIZE - block;
9528
9529 for (i = from; i <= to; i++) {
9530 p = (const unsigned char *)luaL_checklstring(L, i, &n);
9531 pe = p + n;
9532
9533 while (p < pe) {
9534 int in = (int)MIN((size_t)(pe - p), step), out;
9535
9536 if (!EVP_CipherUpdate(ctx, (void *)luaL_prepbuffer(B), &out, p, in))
9537 return 0;
9538
9539 p += in;
9540 luaL_addsize(B, out);
9541 }
9542 }
9543
9544 return 1;
9545} /* cipher_update_() */
9546
9547
9548static int cipher_update(lua_State *L) {
9549 EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
9550 luaL_Buffer B;
9551
9552 luaL_buffinit(L, &B);
9553
9554 if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L)))
9555 goto sslerr;
9556
9557 luaL_pushresult(&B);
9558
9559 return 1;
9560sslerr:
9561 lua_pushnil(L);
9562 auxL_pusherror(L, auxL_EOPENSSL, NULL);
9563
9564 return 2;
9565} /* cipher_update() */
9566
9567
9568static int cipher_final(lua_State *L) {
9569 EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
9570 luaL_Buffer B;
9571 size_t block;
9572 int out;
9573
9574 luaL_buffinit(L, &B);
9575
9576 if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L)))
9577 goto sslerr;
9578
9579 block = EVP_CIPHER_CTX_block_size(ctx);
9580
9581 if (LUAL_BUFFERSIZE < block)
9582 return luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%d) < EVP_CIPHER_CTX_block_size(%d)", (int)LUAL_BUFFERSIZE, (int)block);
9583
9584 if (!EVP_CipherFinal(ctx, (void *)luaL_prepbuffer(&B), &out))
9585 goto sslerr;
9586
9587 luaL_addsize(&B, out);
9588 luaL_pushresult(&B);
9589
9590 return 1;
9591sslerr:
9592 lua_pushnil(L);
9593 auxL_pusherror(L, auxL_EOPENSSL, NULL);
9594
9595 return 2;
9596} /* cipher_final() */
9597
9598
9599static int cipher__gc(lua_State *L) {
9600 EVP_CIPHER_CTX **ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
9601
9602 EVP_CIPHER_CTX_free(*ctx);
9603 *ctx = NULL;
9604
9605 return 0;
9606} /* cipher__gc() */
9607
9608
9609static const auxL_Reg cipher_methods[] = {
9610 { "encrypt", &cipher_encrypt },
9611 { "decrypt", &cipher_decrypt },
9612 { "update", &cipher_update },
9613 { "final", &cipher_final },
9614 { NULL, NULL },
9615};
9616
9617static const auxL_Reg cipher_metatable[] = {
9618 { "__gc", &cipher__gc },
9619 { NULL, NULL },
9620};
9621
9622static const auxL_Reg cipher_globals[] = {
9623 { "new", &cipher_new },
9624 { "interpose", &cipher_interpose },
9625 { NULL, NULL },
9626};
9627
9628int luaopen__openssl_cipher(lua_State *L) {
9629 initall(L);
9630
9631 auxL_newlib(L, cipher_globals, 0);
9632
9633 return 1;
9634} /* luaopen__openssl_cipher() */
9635
9636
9637/*
9638 * OCSP_RESPONSE - openssl.ocsp.response
9639 *
9640 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
9641
9642static int or_tostring(lua_State *L) {
9643 OCSP_RESPONSE *resp = checksimple(L, 1, OCSP_RESPONSE_CLASS);
9644 BIO *bio = getbio(L);
9645 size_t len;
9646 char *bytes;
9647
9648 if (!OCSP_RESPONSE_print(bio, resp, 0))
9649 return auxL_error(L, auxL_EOPENSSL, "OCSP_RESPONSE:tostring");
9650
9651 len = BIO_get_mem_data(bio, &bytes);
9652 lua_pushlstring(L, bytes, len);
9653
9654 return 1;
9655} /* or__tostring() */
9656
9657
9658static int or_toPEM(lua_State *L) {
9659 OCSP_RESPONSE *resp = checksimple(L, 1, OCSP_RESPONSE_CLASS);
9660 BIO *bio = getbio(L);
9661 size_t len;
9662 char *bytes;
9663
9664 if (!PEM_write_bio_OCSP_RESPONSE(bio, resp))
9665 return auxL_error(L, auxL_EOPENSSL, "OCSP_RESPONSE:toPEM");
9666
9667 len = BIO_get_mem_data(bio, &bytes);
9668 lua_pushlstring(L, bytes, len);
9669
9670 return 1;
9671} /* or_toPEM() */
9672
9673
9674static int or_getBasic(lua_State *L) {
9675 OCSP_RESPONSE *resp = checksimple(L, 1, OCSP_RESPONSE_CLASS);
9676
9677 OCSP_BASICRESP **basic = prepsimple(L, OCSP_BASICRESP_CLASS);
9678
9679 *basic = OCSP_response_get1_basic(resp);
9680 if (!*basic)
9681 return auxL_error(L, auxL_EOPENSSL, "OCSP_RESPONSE:getBasic");
9682
9683 return 1;
9684} /* or_getBasic() */
9685
9686
9687static int or__gc(lua_State *L) {
9688 OCSP_RESPONSE **ud = luaL_checkudata(L, 1, OCSP_RESPONSE_CLASS);
9689
9690 if (*ud) {
9691 OCSP_RESPONSE_free(*ud);
9692 *ud = NULL;
9693 }
9694
9695 return 0;
9696} /* or__gc() */
9697
9698static const auxL_Reg or_methods[] = {
9699 { "tostring", &or_tostring },
9700 { "toPEM", &or_toPEM },
9701 { "getBasic", &or_getBasic },
9702 { NULL, NULL },
9703};
9704
9705static const auxL_Reg or_metatable[] = {
9706 { "__tostring", &or_tostring },
9707 { "__gc", &or__gc },
9708 { NULL, NULL },
9709};
9710
9711static const auxL_Reg or_globals[] = {
9712 { NULL, NULL },
9713};
9714
9715int luaopen__openssl_ocsp_response(lua_State *L) {
9716 initall(L);
9717
9718 auxL_newlib(L, or_globals, 0);
9719
9720 return 1;
9721} /* luaopen__openssl_ocsp_response() */
9722
9723
9724/*
9725 * OCSP_BASICRESP - openssl.ocsp.basic
9726 *
9727 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
9728
9729static int ob_verify(lua_State *L) {
9730 OCSP_BASICRESP *basic = checksimple(L, 1, OCSP_BASICRESP_CLASS);
9731 STACK_OF(X509) *certs = testsimple(L, 2, X509_CHAIN_CLASS);
9732 X509_STORE *store = testsimple(L, 3, X509_STORE_CLASS);
9733 unsigned long flags = luaL_optinteger(L, 4, 0);
9734
9735 int res = OCSP_basic_verify(basic, certs, store, flags);
9736 if (res == -1)
9737 return auxL_error(L, auxL_EOPENSSL, "OCSP_BASICRESP:verify");
9738
9739 lua_pushboolean(L, res);
9740 if (res) {
9741 return 1;
9742 } else {
9743 auxL_pusherror(L, auxL_EOPENSSL, NULL);
9744 return 2;
9745 }
9746} /* ob_verify() */
9747
9748
9749static int ob__gc(lua_State *L) {
9750 OCSP_BASICRESP **ud = luaL_checkudata(L, 1, OCSP_BASICRESP_CLASS);
9751
9752 if (*ud) {
9753 OCSP_BASICRESP_free(*ud);
9754 *ud = NULL;
9755 }
9756
9757 return 0;
9758} /* or__gc() */
9759
9760
9761static const auxL_Reg ob_methods[] = {
9762 { "verify", &ob_verify },
9763 { NULL, NULL },
9764};
9765
9766static const auxL_Reg ob_metatable[] = {
9767 { "__gc", &ob__gc },
9768 { NULL, NULL },
9769};
9770
9771static const auxL_Reg ob_globals[] = {
9772 { NULL, NULL },
9773};
9774
9775static const auxL_IntegerReg ob_verify_flags[] = {
9776 { "NOSIGS", OCSP_NOSIGS},
9777 { "NOVERIFY", OCSP_NOVERIFY},
9778 { "NOCHAIN", OCSP_NOCHAIN},
9779 { "NOCHECKS", OCSP_NOCHECKS},
9780 { "NOEXPLICIT", OCSP_NOEXPLICIT},
9781 { "TRUSTOTHER", OCSP_TRUSTOTHER},
9782 { "NOINTERN", OCSP_NOINTERN},
9783 { "TRUSTOTHER", OCSP_TRUSTOTHER},
9784 { NULL, 0 },
9785};
9786
9787int luaopen__openssl_ocsp_basic(lua_State *L) {
9788 initall(L);
9789
9790 auxL_newlib(L, ob_globals, 0);
9791 auxL_setintegers(L, ob_verify_flags);
9792
9793 return 1;
9794} /* luaopen__openssl_ocsp_basic() */
9795
9796
9797/*
9798 * Rand - openssl.rand
9799 *
9800 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
9801
9802struct randL_state {
9803 pid_t pid;
9804}; /* struct randL_state */
9805
9806static struct randL_state *randL_getstate(lua_State *L) {
9807 return lua_touserdata(L, lua_upvalueindex(1));
9808} /* randL_getstate() */
9809
9810#if HAVE_SYS_SYSCALL_H
9811#include <sys/syscall.h> /* SYS_getrandom syscall(2) */
9812#endif
9813
9814#if HAVE_SYS_SYSCTL_H
9815#include <sys/sysctl.h> /* CTL_KERN KERN_RANDOM RANDOM_UUID sysctl(2) */
9816#endif
9817
9818static int randL_stir(struct randL_state *st, unsigned rqstd) {
9819 unsigned count = 0;
9820 int error;
9821 unsigned char data[256];
9822
9823#if HAVE_ARC4RANDOM_BUF
9824 while (count < rqstd) {
9825 size_t n = MIN(rqstd - count, sizeof data);
9826
9827 arc4random_buf(data, n);
9828
9829 RAND_seed(data, n);
9830
9831 count += n;
9832 }
9833#endif
9834
9835#if HAVE_SYSCALL && HAVE_DECL_SYS_GETRANDOM
9836 while (count < rqstd) {
9837 size_t lim = MIN(rqstd - count, sizeof data);
9838 int n;
9839
9840 n = syscall(SYS_getrandom, data, lim, 0);
9841
9842 if (n == -1) {
9843 break;
9844 }
9845
9846 RAND_seed(data, n);
9847
9848 count += n;
9849 }
9850#endif
9851
9852#if HAVE_SYS_SYSCTL_H && HAVE_DECL_RANDOM_UUID
9853 while (count < rqstd) {
9854 int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
9855 size_t n = MIN(rqstd - count, sizeof data);
9856
9857 if (0 != sysctl(mib, countof(mib), data, &n, (void *)0, 0))
9858 break;
9859
9860 RAND_seed(data, n);
9861
9862 count += n;
9863 }
9864
9865#endif
9866
9867 if (count < rqstd) {
9868#if defined O_CLOEXEC && (!defined _AIX /* O_CLOEXEC overflows int */)
9869 int fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC);
9870#else
9871 int fd = open("/dev/urandom", O_RDONLY);
9872#endif
9873
9874 if (fd == -1)
9875 goto syserr;
9876
9877 while (count < rqstd) {
9878 ssize_t n = read(fd, data, MIN(rqstd - count, sizeof data));
9879
9880 switch (n) {
9881 case 0:
9882 errno = EIO;
9883
9884 /* FALL THROUGH */
9885 case -1:
9886 if (errno == EINTR)
9887 continue;
9888
9889 error = errno;
9890
9891 close(fd);
9892
9893 goto error;
9894 default:
9895 RAND_seed(data, n);
9896
9897 count += n;
9898 }
9899 }
9900
9901 close(fd);
9902 }
9903
9904 st->pid = getpid();
9905
9906 return 0;
9907syserr:
9908 error = errno;
9909error:;
9910 struct {
9911 struct timeval tv;
9912 pid_t pid;
9913 struct rusage ru;
9914 struct utsname un;
9915 uintptr_t aslr;
9916#if defined __APPLE__
9917 uint64_t mt;
9918#elif defined __sun
9919 struct timespec mt;
9920#endif
9921 } junk;
9922
9923 gettimeofday(&junk.tv, NULL);
9924 junk.pid = getpid();
9925 getrusage(RUSAGE_SELF, &junk.ru);
9926 uname(&junk.un);
9927 junk.aslr = (uintptr_t)&strcpy ^ (uintptr_t)&randL_stir;
9928#if defined __APPLE__
9929 junk.mt = mach_absolute_time();
9930#elif defined __sun
9931 /*
9932 * NOTE: Linux requires -lrt for clock_gettime, and in any event
9933 * should have RANDOM_UUID or getrandom. (Though, some middle-aged
9934 * kernels might have neither). The BSDs have arc4random which
9935 * should be using KERN_URND, KERN_ARND, and more recently
9936 * getentropy. (Though, again, some older BSD kernels used an
9937 * arc4random implementation that opened /dev/urandom.)
9938 *
9939 * Just do this for Solaris to keep things simple. We've already
9940 * crossed the line of what can be reasonably accomplished on
9941 * unreasonable platforms.
9942 */
9943 clock_gettime(CLOCK_MONOTONIC, &junk.mt);
9944#endif
9945
9946 RAND_add(&junk, sizeof junk, 0.1);
9947
9948 st->pid = getpid();
9949
9950 return error;
9951} /* randL_stir() */
9952
9953
9954static void randL_checkpid(struct randL_state *st) {
9955 if (st->pid != getpid())
9956 (void)randL_stir(st, 16);
9957} /* randL_checkpid() */
9958
9959
9960static int rand_stir(lua_State *L) {
9961 int error = randL_stir(randL_getstate(L), auxL_optunsigned(L, 1, 16, 0, UINT_MAX));
9962
9963 if (error) {
9964 lua_pushboolean(L, 0);
9965 lua_pushstring(L, aux_strerror(error));
9966 lua_pushinteger(L, error);
9967
9968 return 3;
9969 } else {
9970 lua_pushboolean(L, 1);
9971
9972 return 1;
9973 }
9974} /* rand_stir() */
9975
9976
9977static int rand_add(lua_State *L) {
9978 const void *buf;
9979 size_t len;
9980 lua_Number entropy;
9981
9982 buf = luaL_checklstring(L, 1, &len);
9983 entropy = luaL_optnumber(L, 2, len);
9984
9985 RAND_add(buf, len, entropy);
9986
9987 lua_pushboolean(L, 1);
9988
9989 return 1;
9990} /* rand_add() */
9991
9992
9993static int rand_bytes(lua_State *L) {
9994 int size = luaL_checkinteger(L, 1);
9995 luaL_Buffer B;
9996 int count = 0, n;
9997
9998 randL_checkpid(randL_getstate(L));
9999
10000 luaL_buffinit(L, &B);
10001
10002 while (count < size) {
10003 n = MIN((size - count), LUAL_BUFFERSIZE);
10004
10005 if (!RAND_bytes((void *)luaL_prepbuffer(&B), n))
10006 return auxL_error(L, auxL_EOPENSSL, "rand.bytes");
10007
10008 luaL_addsize(&B, n);
10009 count += n;
10010 }
10011
10012 luaL_pushresult(&B);
10013
10014 return 1;
10015} /* rand_bytes() */
10016
10017
10018static int rand_ready(lua_State *L) {
10019 lua_pushboolean(L, RAND_status() == 1);
10020
10021 return 1;
10022} /* rand_ready() */
10023
10024
10025static unsigned long long rand_llu(lua_State *L) {
10026 unsigned long long llu;
10027
10028 if (!RAND_bytes((void *)&llu, sizeof llu))
10029 auxL_error(L, auxL_EOPENSSL, "rand.uniform");
10030
10031 return llu;
10032} /* rand_llu() */
10033
10034/*
10035 * The following algorithm for rand_uniform() is taken from OpenBSD's
10036 * arc4random_uniform, written by Otto Moerbeek, with subsequent
10037 * simplification by Jorden Verwer. Otto's source code comment reads
10038 *
10039 * Uniformity is achieved by generating new random numbers until the one
10040 * returned is outside the range [0, 2**32 % upper_bound). This guarantees
10041 * the selected random number will be inside [2**32 % upper_bound, 2**32)
10042 * which maps back to [0, upper_bound) after reduction modulo upper_bound.
10043 *
10044 * --
10045 * A more bit-efficient approach by the eminent statistician Herman Rubin
10046 * can be found in this sci.crypt Usenet post.
10047 *
10048 * From: hrubin@odds.stat.purdue.edu (Herman Rubin)
10049 * Newsgroups: sci.crypt
10050 * Subject: Re: Generating a random number between 0 and N-1
10051 * Date: 14 Nov 2002 11:20:37 -0500
10052 * Organization: Purdue University Statistics Department
10053 * Lines: 40
10054 * Message-ID: <ar0igl$1ak2@odds.stat.purdue.edu>
10055 * References: <yO%y9.19646$RO1.373975@weber.videotron.net> <3DCD8D75.40408@nospam.com>
10056 * NNTP-Posting-Host: odds.stat.purdue.edu
10057 * X-Trace: mozo.cc.purdue.edu 1037290837 9316 128.210.141.13 (14 Nov 2002 16:20:37 GMT)
10058 * X-Complaints-To: ne...@news.purdue.edu
10059 * NNTP-Posting-Date: Thu, 14 Nov 2002 16:20:37 +0000 (UTC)
10060 * Xref: archiver1.google.com sci.crypt:78935
10061 *
10062 * In article <3DCD8D7...@nospam.com>,
10063 * Michael Amling <nos...@nospam.com> wrote:
10064 * >Carlos Moreno wrote:
10065 *
10066 * I have already posted on this, but a repeat might be
10067 * in order.
10068 *
10069 * If one can trust random bits, the most bitwise efficient
10070 * manner to get a single random integer between 0 and N-1
10071 * can be obtained as follows; the code can be made more
10072 * computationally efficient. I believe it is easier to
10073 * understand with gotos. I am assuming N>1.
10074 *
10075 * i = 0; j = 1;
10076 *
10077 * loop: j=2*j; i=2*i+RANBIT;
10078 * if (j < N) goto loop;
10079 * if (i >= N) {
10080 * i = i - N;
10081 * j = j - N;
10082 * goto loop:}
10083 * else return (i);
10084 *
10085 * The algorithm works because at each stage i is uniform
10086 * between 0 and j-1.
10087 *
10088 * Another possibility is to generate k bits, where 2^k >= N.
10089 * If 2^k = c*N + remainder, generate the appropriate value
10090 * if a k-bit random number is less than c*N.
10091 *
10092 * For N = 17 (numbers just larger than powers of 2 are "bad"),
10093 * the amount of information is about 4.09 bits, the best
10094 * algorithm to generate one random number takes about 5.765
10095 * bits, taking k = 5 uses 9.412 bits, taking k = 6 or 7 uses
10096 * 7.529 bits. These are averages, but the tails are not bad.
10097 *
10098 * (https://groups.google.com/forum/message/raw?msg=sci.crypt/DMslf6tSrD8/rv9rk6oP3r4J)
10099 */
10100static int rand_uniform(lua_State *L) {
10101 unsigned long long r;
10102
10103 randL_checkpid(randL_getstate(L));
10104
10105 if (lua_isnoneornil(L, 1)) {
10106 r = rand_llu(L);
10107 } else {
10108 unsigned long long N, m;
10109
10110 N = auxL_checkunsigned(L, 1);
10111
10112 luaL_argcheck(L, N > 1, 1, lua_pushfstring(L, "[0, %d): interval is empty", (int)N));
10113
10114 m = -N % N;
10115
10116 do {
10117 r = rand_llu(L);
10118 } while (r < m);
10119
10120 r = r % N;
10121 }
10122
10123 auxL_pushunsigned(L, r);
10124
10125 return 1;
10126} /* rand_uniform() */
10127
10128
10129static const auxL_Reg rand_globals[] = {
10130 { "stir", &rand_stir },
10131 { "add", &rand_add },
10132 { "bytes", &rand_bytes },
10133 { "ready", &rand_ready },
10134 { "uniform", &rand_uniform },
10135 { NULL, NULL },
10136};
10137
10138int luaopen__openssl_rand(lua_State *L) {
10139 struct randL_state *st;
10140
10141 initall(L);
10142
10143 st = lua_newuserdata(L, sizeof *st);
10144 memset(st, 0, sizeof *st);
10145 auxL_newlib(L, rand_globals, 1);
10146
10147 return 1;
10148} /* luaopen__openssl_rand() */
10149
10150
10151/*
10152 * DES - openssl.des
10153 *
10154 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10155
10156static int de5_string_to_key(lua_State *L) {
10157 DES_cblock key;
10158
10159 DES_string_to_key(luaL_checkstring(L, 1), &key);
10160 lua_pushlstring(L, (char *)key, sizeof key);
10161
10162 return 1;
10163} /* de5_string_to_key() */
10164
10165static int de5_set_odd_parity(lua_State *L) {
10166 const char *src;
10167 size_t len;
10168 DES_cblock key;
10169
10170 src = luaL_checklstring(L, 1, &len);
10171 memset(&key, 0, sizeof key);
10172 memcpy(&key, src, MIN(len, sizeof key));
10173
10174 DES_set_odd_parity(&key);
10175 lua_pushlstring(L, (char *)key, sizeof key);
10176
10177 return 1;
10178} /* de5_set_odd_parity() */
10179
10180static const auxL_Reg des_globals[] = {
10181 { "string_to_key", &de5_string_to_key },
10182 { "set_odd_parity", &de5_set_odd_parity },
10183 { NULL, NULL },
10184};
10185
10186int luaopen__openssl_des(lua_State *L) {
10187 initall(L);
10188
10189 auxL_newlib(L, des_globals, 0);
10190
10191 return 1;
10192} /* luaopen__openssl_des() */
10193
10194
10195/*
10196 * Multithread Reentrancy Protection
10197 *
10198 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10199
10200static struct {
10201 pthread_mutex_t *lock;
10202 int nlock;
10203} mt_state;
10204
10205static void mt_lock(int mode, int type, const char *file NOTUSED, int line NOTUSED) {
10206 if (mode & CRYPTO_LOCK)
10207 pthread_mutex_lock(&mt_state.lock[type]);
10208 else
10209 pthread_mutex_unlock(&mt_state.lock[type]);
10210} /* mt_lock() */
10211
10212/*
10213 * Sources include Google and especially the Wine Project. See get_unix_tid
10214 * at http://source.winehq.org/git/wine.git/?a=blob;f=dlls/ntdll/server.c.
10215 */
10216#if __FreeBSD__
10217#include <sys/thr.h> /* thr_self(2) */
10218#elif __NetBSD__
10219#include <lwp.h> /* _lwp_self(2) */
10220#endif
10221
10222static unsigned long mt_gettid(void) {
10223#if __APPLE__
10224 return pthread_mach_thread_np(pthread_self());
10225#elif __DragonFly__
10226 return lwp_gettid();
10227#elif __FreeBSD__
10228 long id;
10229
10230 thr_self(&id);
10231
10232 return id;
10233#elif __NetBSD__
10234 return _lwp_self();
10235#else
10236 /*
10237 * pthread_t is an integer on Solaris and Linux, an unsigned integer
10238 * on AIX, and a unique pointer on OpenBSD.
10239 */
10240 return (unsigned long)pthread_self();
10241#endif
10242} /* mt_gettid() */
10243
10244static int mt_init(void) {
10245 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
10246 static int done, bound;
10247 int error = 0;
10248
10249 if ((error = pthread_mutex_lock(&mutex)))
10250 return error;
10251
10252 if (done)
10253 goto epilog;
10254
10255 if (!CRYPTO_get_locking_callback()) {
10256 if (!mt_state.lock) {
10257 int i;
10258
10259 mt_state.nlock = CRYPTO_num_locks();
10260
10261 if (!(mt_state.lock = malloc(mt_state.nlock * sizeof *mt_state.lock))) {
10262 error = errno;
10263 goto epilog;
10264 }
10265
10266 for (i = 0; i < mt_state.nlock; i++) {
10267 if ((error = pthread_mutex_init(&mt_state.lock[i], NULL))) {
10268 while (i > 0) {
10269 pthread_mutex_destroy(&mt_state.lock[--i]);
10270 }
10271
10272 free(mt_state.lock);
10273 mt_state.lock = NULL;
10274
10275 goto epilog;
10276 }
10277 }
10278 }
10279
10280 CRYPTO_set_locking_callback(&mt_lock);
10281 bound = 1;
10282 }
10283
10284 if (!CRYPTO_get_id_callback()) {
10285 CRYPTO_set_id_callback(&mt_gettid);
10286 bound = 1;
10287 }
10288
10289 if (bound && (error = dl_anchor()))
10290 goto epilog;
10291
10292 done = 1;
10293epilog:
10294 pthread_mutex_unlock(&mutex);
10295
10296 return error;
10297} /* mt_init() */
10298
10299
10300static void initall(lua_State *L) {
10301 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
10302 static int initssl;
10303 int error;
10304
10305 if ((error = mt_init()))
10306 auxL_error(L, error, "openssl.init");
10307
10308 pthread_mutex_lock(&mutex);
10309
10310 if (!initssl) {
10311 initssl = 1;
10312
10313 SSL_load_error_strings();
10314 SSL_library_init();
10315 OpenSSL_add_all_algorithms();
10316
10317 /*
10318 * TODO: Figure out a way to detect whether OpenSSL has
10319 * already been configured.
10320 */
10321 OPENSSL_config(NULL);
10322 }
10323
10324 pthread_mutex_unlock(&mutex);
10325
10326 if ((error = compat_init()))
10327 auxL_error(L, error, "openssl.init");
10328
10329 if ((error = ex_init()))
10330 auxL_error(L, error, "openssl.init");
10331
10332 ex_newstate(L);
10333
10334 auxL_addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable, 0);
10335 pk_luainit(L, 0);
10336#ifndef OPENSSL_NO_EC
10337 auxL_addclass(L, EC_GROUP_CLASS, ecg_methods, ecg_metatable, 0);
10338#endif
10339 auxL_addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable, 0);
10340 auxL_addclass(L, X509_GENS_CLASS, gn_methods, gn_metatable, 0);
10341 auxL_addclass(L, X509_EXT_CLASS, xe_methods, xe_metatable, 0);
10342 auxL_addclass(L, X509_CERT_CLASS, xc_methods, xc_metatable, 0);
10343 auxL_addclass(L, X509_CSR_CLASS, xr_methods, xr_metatable, 0);
10344 auxL_addclass(L, X509_CRL_CLASS, xx_methods, xx_metatable, 0);
10345 auxL_addclass(L, X509_CHAIN_CLASS, xl_methods, xl_metatable, 0);
10346 auxL_addclass(L, X509_STORE_CLASS, xs_methods, xs_metatable, 0);
10347 auxL_addclass(L, X509_VERIFY_PARAM_CLASS, xp_methods, xp_metatable, 0);
10348 auxL_addclass(L, PKCS12_CLASS, p12_methods, p12_metatable, 0);
10349 auxL_addclass(L, SSL_CTX_CLASS, sx_methods, sx_metatable, 0);
10350 auxL_addclass(L, SSL_CLASS, ssl_methods, ssl_metatable, 0);
10351 auxL_addclass(L, DIGEST_CLASS, md_methods, md_metatable, 0);
10352 auxL_addclass(L, HMAC_CLASS, hmac_methods, hmac_metatable, 0);
10353 auxL_addclass(L, CIPHER_CLASS, cipher_methods, cipher_metatable, 0);
10354 auxL_addclass(L, OCSP_RESPONSE_CLASS, or_methods, or_metatable, 0);
10355 auxL_addclass(L, OCSP_BASICRESP_CLASS, ob_methods, ob_metatable, 0);
10356} /* initall() */
10357
diff --git a/src/openssl.cipher.lua b/src/openssl.cipher.lua
new file mode 100644
index 0000000..876cd1b
--- /dev/null
+++ b/src/openssl.cipher.lua
@@ -0,0 +1,3 @@
1local ctx = require"_openssl.cipher"
2
3return ctx
diff --git a/src/openssl.des.lua b/src/openssl.des.lua
new file mode 100644
index 0000000..449267c
--- /dev/null
+++ b/src/openssl.des.lua
@@ -0,0 +1,3 @@
1local ctx = require"_openssl.des"
2
3return ctx
diff --git a/src/openssl.digest.lua b/src/openssl.digest.lua
new file mode 100644
index 0000000..87cc958
--- /dev/null
+++ b/src/openssl.digest.lua
@@ -0,0 +1,3 @@
1local ctx = require"_openssl.digest"
2
3return ctx
diff --git a/src/openssl.hmac.lua b/src/openssl.hmac.lua
new file mode 100644
index 0000000..e622d1d
--- /dev/null
+++ b/src/openssl.hmac.lua
@@ -0,0 +1,3 @@
1local ctx = require"_openssl.hmac"
2
3return ctx
diff --git a/src/openssl.lua b/src/openssl.lua
new file mode 100644
index 0000000..cce2150
--- /dev/null
+++ b/src/openssl.lua
@@ -0,0 +1 @@
return require"_openssl"
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 @@
1local ob = require "_openssl.ocsp.basic"
2
3return 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 @@
1local ocsp_response = require "_openssl.ocsp.response"
2
3return ocsp_response
diff --git a/src/openssl.pkcs12.lua b/src/openssl.pkcs12.lua
new file mode 100644
index 0000000..d8f70c2
--- /dev/null
+++ b/src/openssl.pkcs12.lua
@@ -0,0 +1 @@
return require('_openssl.pkcs12')
diff --git a/src/openssl.pkey.lua b/src/openssl.pkey.lua
new file mode 100644
index 0000000..2cbd6d2
--- /dev/null
+++ b/src/openssl.pkey.lua
@@ -0,0 +1,4 @@
1local pkey = require"_openssl.pkey"
2
3return pkey
4
diff --git a/src/openssl.pubkey.lua b/src/openssl.pubkey.lua
new file mode 100644
index 0000000..91bc8b9
--- /dev/null
+++ b/src/openssl.pubkey.lua
@@ -0,0 +1,2 @@
1-- for backwards compatibility
2return require "openssl.pkey"
diff --git a/src/openssl.rand.lua b/src/openssl.rand.lua
new file mode 100644
index 0000000..70e9d3f
--- /dev/null
+++ b/src/openssl.rand.lua
@@ -0,0 +1,3 @@
1local ctx = require"_openssl.rand"
2
3return ctx
diff --git a/src/openssl.ssl.context.lua b/src/openssl.ssl.context.lua
new file mode 100644
index 0000000..2098b54
--- /dev/null
+++ b/src/openssl.ssl.context.lua
@@ -0,0 +1,16 @@
1local ctx = require"_openssl.ssl.context"
2
3local pack = table.pack or function(...) return { n = select("#", ...); ... } end
4
5-- Allow passing a vararg of ciphers, or an array
6local setCipherList; setCipherList = ctx.interpose("setCipherList", function (self, ciphers, ...)
7 if (...) then
8 local ciphers_t = pack(ciphers, ...)
9 ciphers = table.concat(ciphers_t, ":", 1, ciphers_t.n)
10 elseif type(ciphers) == "table" then
11 ciphers = table.concat(ciphers, ":")
12 end
13 return setCipherList(self, ciphers)
14end)
15
16return ctx
diff --git a/src/openssl.ssl.lua b/src/openssl.ssl.lua
new file mode 100644
index 0000000..3c348f6
--- /dev/null
+++ b/src/openssl.ssl.lua
@@ -0,0 +1,3 @@
1local ctx = require"_openssl.ssl"
2
3return ctx
diff --git a/src/openssl.x509.altname.lua b/src/openssl.x509.altname.lua
new file mode 100644
index 0000000..e8222a0
--- /dev/null
+++ b/src/openssl.x509.altname.lua
@@ -0,0 +1,14 @@
1local altname = require"_openssl.x509.altname"
2local auxlib = require"openssl.auxlib"
3
4altname.interpose("__tostring", function (self)
5 local t = { }
6
7 for k, v in auxlib.pairs(self) do
8 t[#t + 1] = k .. ":" .. v
9 end
10
11 return table.concat(t, ", ")
12end)
13
14return altname
diff --git a/src/openssl.x509.chain.lua b/src/openssl.x509.chain.lua
new file mode 100644
index 0000000..e89dec8
--- /dev/null
+++ b/src/openssl.x509.chain.lua
@@ -0,0 +1,3 @@
1local chain = require"_openssl.x509.chain"
2
3return chain
diff --git a/src/openssl.x509.crl.lua b/src/openssl.x509.crl.lua
new file mode 100644
index 0000000..7f8a019
--- /dev/null
+++ b/src/openssl.x509.crl.lua
@@ -0,0 +1 @@
return require('_openssl.x509.crl')
diff --git a/src/openssl.x509.csr.lua b/src/openssl.x509.csr.lua
new file mode 100644
index 0000000..c909ceb
--- /dev/null
+++ b/src/openssl.x509.csr.lua
@@ -0,0 +1 @@
return require('_openssl.x509.csr')
diff --git a/src/openssl.x509.extension.lua b/src/openssl.x509.extension.lua
new file mode 100644
index 0000000..7043f45
--- /dev/null
+++ b/src/openssl.x509.extension.lua
@@ -0,0 +1 @@
return require('_openssl.x509.extension')
diff --git a/src/openssl.x509.lua b/src/openssl.x509.lua
new file mode 100644
index 0000000..278baf5
--- /dev/null
+++ b/src/openssl.x509.lua
@@ -0,0 +1,3 @@
1local x509 = require"_openssl.x509.cert"
2
3return x509
diff --git a/src/openssl.x509.name.lua b/src/openssl.x509.name.lua
new file mode 100644
index 0000000..f33339a
--- /dev/null
+++ b/src/openssl.x509.name.lua
@@ -0,0 +1,14 @@
1local name = require"_openssl.x509.name"
2local auxlib = require"openssl.auxlib"
3
4name.interpose("__tostring", function (self)
5 local t = { }
6
7 for k, v in auxlib.pairs(self) do
8 t[#t + 1] = k .. "=" .. v
9 end
10
11 return table.concat(t, ", ")
12end)
13
14return name
diff --git a/src/openssl.x509.store.lua b/src/openssl.x509.store.lua
new file mode 100644
index 0000000..a717870
--- /dev/null
+++ b/src/openssl.x509.store.lua
@@ -0,0 +1,3 @@
1local store = require"_openssl.x509.store"
2
3return store
diff --git a/src/openssl.x509.verify_param.lua b/src/openssl.x509.verify_param.lua
new file mode 100644
index 0000000..a3148e6
--- /dev/null
+++ b/src/openssl.x509.verify_param.lua
@@ -0,0 +1 @@
return require('_openssl.x509.verify_param')