diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/GNUmakefile | 232 | ||||
-rw-r--r-- | src/Makefile | 7 | ||||
-rw-r--r-- | src/compat52.h | 178 | ||||
-rw-r--r-- | src/openssl.auxlib.lua | 21 | ||||
-rw-r--r-- | src/openssl.bignum.lua | 3 | ||||
-rw-r--r-- | src/openssl.c | 10357 | ||||
-rw-r--r-- | src/openssl.cipher.lua | 3 | ||||
-rw-r--r-- | src/openssl.des.lua | 3 | ||||
-rw-r--r-- | src/openssl.digest.lua | 3 | ||||
-rw-r--r-- | src/openssl.hmac.lua | 3 | ||||
-rw-r--r-- | src/openssl.lua | 1 | ||||
-rw-r--r-- | src/openssl.ocsp.basic.lua | 3 | ||||
-rw-r--r-- | src/openssl.ocsp.response.lua | 3 | ||||
-rw-r--r-- | src/openssl.pkcs12.lua | 1 | ||||
-rw-r--r-- | src/openssl.pkey.lua | 4 | ||||
-rw-r--r-- | src/openssl.pubkey.lua | 2 | ||||
-rw-r--r-- | src/openssl.rand.lua | 3 | ||||
-rw-r--r-- | src/openssl.ssl.context.lua | 16 | ||||
-rw-r--r-- | src/openssl.ssl.lua | 3 | ||||
-rw-r--r-- | src/openssl.x509.altname.lua | 14 | ||||
-rw-r--r-- | src/openssl.x509.chain.lua | 3 | ||||
-rw-r--r-- | src/openssl.x509.crl.lua | 1 | ||||
-rw-r--r-- | src/openssl.x509.csr.lua | 1 | ||||
-rw-r--r-- | src/openssl.x509.extension.lua | 1 | ||||
-rw-r--r-- | src/openssl.x509.lua | 3 | ||||
-rw-r--r-- | src/openssl.x509.name.lua | 14 | ||||
-rw-r--r-- | src/openssl.x509.store.lua | 3 | ||||
-rw-r--r-- | src/openssl.x509.verify_param.lua | 1 |
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 | ||
2 | sp := $(sp).x | ||
3 | dirstack_$(sp) := $(d) | ||
4 | d := $(abspath $(lastword $(MAKEFILE_LIST))/..) | ||
5 | |||
6 | ifeq ($(origin GUARD_$(d)), undefined) | ||
7 | GUARD_$(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 | # | ||
13 | include $(d)/../GNUmakefile | ||
14 | |||
15 | |||
16 | # | ||
17 | # C O M P I L A T I O N F L A G S | ||
18 | # | ||
19 | CPPFLAGS_$(d) = $(ALL_CPPFLAGS) -DHAVE_CONFIG_H | ||
20 | CFLAGS_$(d) = $(ALL_CFLAGS) | ||
21 | SOFLAGS_$(d) = $(ALL_SOFLAGS) | ||
22 | LDFLAGS_$(d) = $(ALL_LDFLAGS) | ||
23 | LIBS_$(d) = $(ALL_LIBS) | ||
24 | |||
25 | # | ||
26 | # C O M P I L A T I O N R U L E S | ||
27 | # | ||
28 | OBJS_$(d) = openssl.o | ||
29 | |||
30 | $(d)/config.h: $(abspath $(d)/..)/config.h | ||
31 | $(CP) $< $@ | ||
32 | |||
33 | define 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 | |||
44 | liblua$(1)-openssl openssl$(1) openssl: $$(d)/$(1)/openssl.so | ||
45 | |||
46 | endef # 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 | |||
52 | ifneq "$(filter $(abspath $(d)/..)/%, $(abspath $(firstword $(MAKEFILE_LIST))))" "" | ||
53 | .SECONDARY: all all5.1 all5.2 all5.3 | ||
54 | |||
55 | all5.1: liblua5.1-openssl | ||
56 | all5.2: liblua5.2-openssl | ||
57 | all5.3: liblua5.3-openssl | ||
58 | all: $(foreach API,$(strip $(LUA_APIS)),all$(API)) | ||
59 | |||
60 | endif | ||
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 | # | ||
66 | define INSTALL_$(d) | ||
67 | |||
68 | MODS$(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 | |||
97 | liblua$(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 | |||
128 | liblua$(1)-openssl-install openssl$(1)-install: $$(MODS$(1)_$$(d)) | ||
129 | |||
130 | .PHONY: liblua$(1)-openssl-uninstall openssl$(1)-uninstall | ||
131 | |||
132 | liblua$(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 | |||
139 | endef # 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 | |||
145 | ifneq "$(filter $(abspath $(d)/..)/%, $(abspath $(firstword $(MAKEFILE_LIST))))" "" | ||
146 | |||
147 | .SECONDARY: install5.1 install5.2 install5.3 install | ||
148 | |||
149 | install5.1: liblua5.1-openssl-install | ||
150 | install5.2: liblua5.2-openssl-install | ||
151 | install5.3: liblua5.3-openssl-install | ||
152 | install: $(foreach API,$(strip $(LUA_APIS)),install$(API)) | ||
153 | |||
154 | .PHONY: uninstall5.1 uninstall5.2 uninstall5.3 uninstall | ||
155 | |||
156 | uninstall5.1: liblua5.1-openssl-uninstall | ||
157 | uninstall5.2: liblua5.2-openssl-uninstall | ||
158 | uninstall5.3: liblua5.3-openssl-uninstall | ||
159 | uninstall: $(foreach API,$(strip $(LUA_APIS)),uninstall$(API)) | ||
160 | |||
161 | endif | ||
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 | |||
175 | clean: $(d)/clean | ||
176 | |||
177 | clean~: $(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 | |||
225 | help: $(d)/help | ||
226 | |||
227 | |||
228 | endif # include guard | ||
229 | |||
230 | # non-recursive epilogue | ||
231 | d := $(dirstack_$(sp)) | ||
232 | sp := $(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 | |||
3 | all: | ||
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 | |||
32 | static 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 | |||
49 | static void luaL_setmetatable(lua_State *L, const char *tname) { | ||
50 | luaL_getmetatable(L, tname); | ||
51 | lua_setmetatable(L, -2); | ||
52 | } /* luaL_setmetatable() */ | ||
53 | |||
54 | |||
55 | static 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 | |||
60 | static 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 | |||
75 | static 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 | |||
96 | static 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 | |||
118 | static 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 | |||
124 | static 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 | |||
137 | typedef LUA_UNSIGNED lua_Unsigned; | ||
138 | |||
139 | |||
140 | static void lua_pushunsigned(lua_State *L, lua_Unsigned n) { | ||
141 | lua_pushnumber(L, (lua_Number)n); | ||
142 | } /* lua_pushunsigned() */ | ||
143 | |||
144 | static lua_Unsigned luaL_checkunsigned(lua_State *L, int arg) { | ||
145 | return (lua_Unsigned)luaL_checknumber(L, arg); | ||
146 | } /* luaL_checkunsigned() */ | ||
147 | |||
148 | |||
149 | static 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 | */ | ||
162 | typedef 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 | |||
172 | static 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 @@ | |||
1 | local auxlib = {} | ||
2 | |||
3 | if _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 | ||
17 | else | ||
18 | auxlib.pairs = pairs | ||
19 | end | ||
20 | |||
21 | return 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 @@ | |||
1 | local bignum = require"_openssl.bignum" | ||
2 | |||
3 | return 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 | |||
447 | static 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 | |||
475 | static _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 | |||
483 | static 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 | |||
499 | static 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 | |||
508 | static 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 | |||
522 | static 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 | |||
536 | static int auxL_swapmetatable(lua_State *, const char *); | ||
537 | static int auxL_swapmetasubtable(lua_State *, const char *, const char *); | ||
538 | |||
539 | static 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 | |||
547 | static 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 | |||
555 | static 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 | |||
581 | static _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 */ | ||
595 | static 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 | |||
619 | static 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 | |||
638 | static _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 | |||
651 | static _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 | |||
673 | static 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 */ | ||
686 | static 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 | */ | ||
692 | static 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 | |||
701 | static 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 | |||
730 | static 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 | |||
745 | static 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 | |||
777 | static 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 | |||
784 | static 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 | |||
793 | static 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 | |||
797 | static 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 | |||
806 | static 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 | |||
810 | static 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 | |||
823 | static 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 | |||
833 | static 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 | |||
844 | static 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 | |||
855 | static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def); | ||
856 | |||
857 | static _Bool auxS_isoid(const char *txt) { | ||
858 | return (*txt >= '0' && *txt <= '9'); | ||
859 | } /* auxS_isoid() */ | ||
860 | |||
861 | static _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 | |||
875 | static _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 | |||
896 | typedef int auxref_t; | ||
897 | typedef int auxtype_t; | ||
898 | |||
899 | static void auxL_unref(lua_State *L, auxref_t *ref) { | ||
900 | luaL_unref(L, LUA_REGISTRYINDEX, *ref); | ||
901 | *ref = LUA_NOREF; | ||
902 | } /* auxL_unref() */ | ||
903 | |||
904 | static 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 | |||
910 | NOTUSED 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 | |||
920 | static 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 | |||
933 | static 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 | |||
961 | static 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 | |||
974 | static 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 | |||
987 | static 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 | |||
1006 | static 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 | |||
1013 | static 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 | |||
1033 | static 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 | |||
1037 | static 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 | |||
1044 | typedef struct { | ||
1045 | const char *name; | ||
1046 | auxL_Integer value; | ||
1047 | } auxL_IntegerReg; | ||
1048 | |||
1049 | static 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 | |||
1058 | typedef struct { | ||
1059 | const char *name; | ||
1060 | lua_CFunction func; | ||
1061 | unsigned nups; /* in addition to nups specified to auxL_setfuncs */ | ||
1062 | } auxL_Reg; | ||
1063 | |||
1064 | static 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 | |||
1079 | static 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 | |||
1103 | static 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 | |||
1115 | static _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 | |||
1139 | static _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 | |||
1157 | static 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 | |||
1173 | static 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 | |||
1186 | static 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 | |||
1203 | static 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 | |||
1241 | static 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 | |||
1248 | static 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 | |||
1260 | static 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 | */ | ||
1272 | static 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; | ||
1291 | epilog: | ||
1292 | (void)pthread_mutex_unlock(&mutex); | ||
1293 | |||
1294 | return error; | ||
1295 | dlerr: | ||
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 | |||
1312 | static 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 | |||
1332 | static 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 | |||
1343 | static 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 | |||
1356 | static 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 | |||
1367 | static 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 | |||
1380 | static 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 | |||
1391 | static 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 | |||
1404 | static 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 | |||
1415 | static 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 | |||
1428 | static 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 | |||
1437 | static 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 | |||
1464 | static 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 | |||
1473 | static 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 | |||
1496 | static 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 | |||
1531 | static 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 | |||
1540 | static 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 | |||
1554 | static 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 | |||
1567 | static 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 | |||
1578 | static 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 | |||
1591 | static 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 | |||
1604 | static 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 | |||
1615 | static 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__) | ||
1627 | static 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 | |||
1640 | static 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 | |||
1648 | static 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 | |||
1656 | static 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 | |||
1664 | static 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 | |||
1676 | static 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 | |||
1684 | static 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 | |||
1720 | static 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 | |||
1744 | static 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 | |||
1768 | static 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 */ | ||
1780 | static 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 | |||
1792 | static 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 | |||
1804 | static 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 | |||
1826 | static 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; | ||
1898 | epilog: | ||
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; | ||
1907 | sslerr: | ||
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 | |||
1919 | static 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 | |||
1942 | static 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 | |||
1966 | struct 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 | |||
1975 | struct 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 | |||
1982 | enum { | ||
1983 | EX_SSL_CTX_ALPN_SELECT_CB, | ||
1984 | EX_SSL_CTX_TLSEXT_SERVERNAME_CB, | ||
1985 | }; | ||
1986 | |||
1987 | static 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) | ||
1998 | typedef const CRYPTO_EX_DATA const_CRYPTO_EX_DATA; | ||
1999 | #else | ||
2000 | typedef CRYPTO_EX_DATA const_CRYPTO_EX_DATA; | ||
2001 | #endif | ||
2002 | |||
2003 | static 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 | |||
2012 | static 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 | |||
2031 | static 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; | ||
2059 | epilog: | ||
2060 | (void)pthread_mutex_unlock(&mutex); | ||
2061 | |||
2062 | return error; | ||
2063 | sslerr: | ||
2064 | error = auxL_EOPENSSL; | ||
2065 | |||
2066 | goto epilog; | ||
2067 | } /* ex_init() */ | ||
2068 | |||
2069 | static 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 | |||
2084 | static _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 | |||
2095 | static 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 | |||
2129 | static 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 | |||
2142 | static 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) */ | ||
2166 | static 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 | |||
2204 | static 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 | |||
2215 | int 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 | |||
2233 | static 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 | |||
2243 | static 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 | */ | ||
2251 | static 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 | |||
2387 | static 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 | |||
2412 | int 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 | |||
2452 | static 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 | |||
2462 | static 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 | |||
2472 | static 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 | |||
2480 | static BIGNUM *(checkbig)(lua_State *, int, _Bool *); | ||
2481 | |||
2482 | static 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 | |||
2498 | static 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 | |||
2509 | static int bn_interpose(lua_State *L) { | ||
2510 | return interpose(L, BIGNUM_CLASS); | ||
2511 | } /* bn_interpose() */ | ||
2512 | |||
2513 | |||
2514 | /* return integral part */ | ||
2515 | static 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. */ | ||
2521 | static _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. */ | ||
2536 | static _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. */ | ||
2563 | static _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 | |||
2582 | static 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 */ | ||
2648 | static 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 */ | ||
2664 | static 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 | |||
2682 | static 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 | |||
2693 | static 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 | |||
2719 | static 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 | |||
2733 | static 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 | |||
2746 | static 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 | |||
2759 | static 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 | |||
2772 | static 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 | |||
2785 | static 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 | |||
2798 | static 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 | |||
2817 | static 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 | |||
2830 | static 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 | |||
2843 | static 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 | |||
2856 | static 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 | |||
2871 | static 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 | |||
2886 | static 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 | |||
2896 | static 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 | |||
2906 | static 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 | |||
2917 | static 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 | |||
2928 | static 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 | |||
2940 | static 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 | |||
2954 | static 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 | |||
2968 | static BIO *getbio(lua_State *); | ||
2969 | |||
2970 | static 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; | ||
2992 | sslerr: | ||
2993 | OPENSSL_free(txt); | ||
2994 | |||
2995 | return auxL_error(L, auxL_EOPENSSL, "bignum:toDecimal"); | ||
2996 | } /* bn_toDecimal() */ | ||
2997 | |||
2998 | |||
2999 | static 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; | ||
3021 | sslerr: | ||
3022 | OPENSSL_free(txt); | ||
3023 | |||
3024 | return auxL_error(L, auxL_EOPENSSL, "bignum:toHex"); | ||
3025 | } /* bn_toHex() */ | ||
3026 | |||
3027 | |||
3028 | static 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 | |||
3051 | static 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 | |||
3071 | static 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 | |||
3079 | int 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 | |||
3093 | static 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 | |||
3104 | static 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 | |||
3132 | static 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 | |||
3191 | creat: | ||
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 | } | ||
3379 | done: | ||
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 | |||
3406 | static 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 | |||
3423 | static 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 | |||
3433 | static 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 | |||
3465 | static 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 | ||
3497 | static 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; | ||
3544 | sslerr: | ||
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 | ||
3556 | static 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; | ||
3603 | sslerr: | ||
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 | |||
3614 | static 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 | |||
3636 | static 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 | |||
3660 | static 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 | |||
3767 | static 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 | |||
3780 | enum 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 | |||
3819 | static const char *const pk_rsa_optlist[] = PK_RSA_OPTLIST; | ||
3820 | static const char *const pk_dsa_optlist[] = PK_DSA_OPTLIST; | ||
3821 | static const char *const pk_dh_optlist[] = PK_DH_OPTLIST; | ||
3822 | static const char *const pk_ec_optlist[] = PK_EC_OPTLIST; | ||
3823 | |||
3824 | const 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 | ||
3864 | static EC_GROUP *ecg_dup_nil(lua_State *, const EC_GROUP *); | ||
3865 | #endif | ||
3866 | |||
3867 | static 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 | |||
4008 | static 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; | ||
4149 | sslerr: | ||
4150 | auxL_error(L, auxL_EOPENSSL, "pkey:setParameters"); | ||
4151 | |||
4152 | return; | ||
4153 | } /* pk_setparam() */ | ||
4154 | |||
4155 | |||
4156 | static 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; | ||
4209 | sslerr: | ||
4210 | return auxL_error(L, auxL_EOPENSSL, "pkey:getParameters"); | ||
4211 | } /* pk_getParameters() */ | ||
4212 | |||
4213 | |||
4214 | static 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; | ||
4237 | sslerr: | ||
4238 | return auxL_error(L, auxL_EOPENSSL, "pkey:setParameters"); | ||
4239 | } /* pk_setParameters() */ | ||
4240 | |||
4241 | |||
4242 | static 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 | |||
4268 | static 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 | |||
4296 | static 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 | |||
4317 | static 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 | |||
4329 | static 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 | |||
4346 | static 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 | |||
4355 | static const auxL_Reg pk_globals[] = { | ||
4356 | { "new", &pk_new }, | ||
4357 | { "interpose", &pk_interpose }, | ||
4358 | { NULL, NULL }, | ||
4359 | }; | ||
4360 | |||
4361 | static 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 | |||
4375 | static 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 | |||
4387 | int 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 | */ | ||
4400 | int 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 | |||
4416 | static 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 | |||
4425 | static 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 | |||
4429 | static 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; | ||
4441 | oops: | ||
4442 | lua_pop(L, 1); | ||
4443 | |||
4444 | return NULL; | ||
4445 | } /* ecg_push_by_nid() */ | ||
4446 | |||
4447 | static 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; | ||
4503 | sslerr: | ||
4504 | return auxL_error(L, auxL_EOPENSSL, "group.new"); | ||
4505 | } /* ecg_new() */ | ||
4506 | |||
4507 | static int ecg_interpose(lua_State *L) { | ||
4508 | return interpose(L, EC_GROUP_CLASS); | ||
4509 | } /* ecg_interpose() */ | ||
4510 | |||
4511 | static 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; | ||
4538 | sslerr: | ||
4539 | return auxL_error(L, auxL_EOPENSSL, "group:__tostring"); | ||
4540 | } /* ecg_tostring() */ | ||
4541 | |||
4542 | static int ecg__tostring(lua_State *L) { | ||
4543 | return ecg_tostring(L); | ||
4544 | } /* ecg__tostring() */ | ||
4545 | |||
4546 | static 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 | |||
4557 | static const auxL_Reg ecg_methods[] = { | ||
4558 | { "tostring", &ecg_tostring }, | ||
4559 | { NULL, NULL }, | ||
4560 | }; | ||
4561 | |||
4562 | static const auxL_Reg ecg_metatable[] = { | ||
4563 | { "__tostring", &ecg__tostring }, | ||
4564 | { "__gc", &ecg__gc }, | ||
4565 | { NULL, NULL }, | ||
4566 | }; | ||
4567 | |||
4568 | static const auxL_Reg ecg_globals[] = { | ||
4569 | { "new", &ecg_new }, | ||
4570 | { "interpose", &ecg_interpose }, | ||
4571 | { NULL, NULL }, | ||
4572 | }; | ||
4573 | |||
4574 | #endif /* OPENSSL_NO_EC */ | ||
4575 | |||
4576 | int 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 | |||
4594 | static 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 | |||
4604 | static 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 | |||
4614 | static int xn_interpose(lua_State *L) { | ||
4615 | return interpose(L, X509_NAME_CLASS); | ||
4616 | } /* xn_interpose() */ | ||
4617 | |||
4618 | |||
4619 | static 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 | |||
4643 | static 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 | |||
4694 | static 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 | |||
4728 | static 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 | |||
4738 | static 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 | |||
4750 | static 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 | |||
4763 | static const auxL_Reg xn_methods[] = { | ||
4764 | { "add", &xn_add }, | ||
4765 | { "all", &xn_all }, | ||
4766 | { NULL, NULL }, | ||
4767 | }; | ||
4768 | |||
4769 | static const auxL_Reg xn_metatable[] = { | ||
4770 | { "__pairs", &xn__pairs }, | ||
4771 | { "__gc", &xn__gc }, | ||
4772 | { "__tostring", &xn__tostring }, | ||
4773 | { NULL, NULL }, | ||
4774 | }; | ||
4775 | |||
4776 | |||
4777 | static const auxL_Reg xn_globals[] = { | ||
4778 | { "new", &xn_new }, | ||
4779 | { "interpose", &xn_interpose }, | ||
4780 | { NULL, NULL }, | ||
4781 | }; | ||
4782 | |||
4783 | int 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 | |||
4797 | static 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 | |||
4807 | static 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 | |||
4817 | static int gn_interpose(lua_State *L) { | ||
4818 | return interpose(L, X509_GENS_CLASS); | ||
4819 | } /* gn_interpose() */ | ||
4820 | |||
4821 | |||
4822 | static 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 | |||
4847 | static 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); | ||
4889 | text: | ||
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; | ||
4908 | error: | ||
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 | |||
4918 | static 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 | |||
4998 | static 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 | |||
5007 | static 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 | |||
5019 | static const auxL_Reg gn_methods[] = { | ||
5020 | { "add", &gn_add }, | ||
5021 | { NULL, NULL }, | ||
5022 | }; | ||
5023 | |||
5024 | static const auxL_Reg gn_metatable[] = { | ||
5025 | { "__pairs", &gn__pairs }, | ||
5026 | { "__gc", &gn__gc }, | ||
5027 | { NULL, NULL }, | ||
5028 | }; | ||
5029 | |||
5030 | |||
5031 | static const auxL_Reg gn_globals[] = { | ||
5032 | { "new", &gn_new }, | ||
5033 | { "interpose", &gn_interpose }, | ||
5034 | { NULL, NULL }, | ||
5035 | }; | ||
5036 | |||
5037 | int 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 | |||
5051 | static _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 | |||
5060 | static 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 | |||
5079 | static 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; | ||
5186 | error: | ||
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 | |||
5198 | static int xe_interpose(lua_State *L) { | ||
5199 | return interpose(L, X509_EXT_CLASS); | ||
5200 | } /* xe_interpose() */ | ||
5201 | |||
5202 | |||
5203 | static 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 | |||
5218 | static 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 | |||
5232 | static 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 | |||
5246 | static 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 | |||
5260 | static 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 | |||
5269 | static 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 | |||
5276 | static 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 | |||
5295 | static 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 | |||
5307 | static 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 | |||
5318 | static const auxL_Reg xe_metatable[] = { | ||
5319 | { "__gc", &xe__gc }, | ||
5320 | { NULL, NULL }, | ||
5321 | }; | ||
5322 | |||
5323 | |||
5324 | static const auxL_Reg xe_globals[] = { | ||
5325 | { "new", &xe_new }, | ||
5326 | { "interpose", &xe_interpose }, | ||
5327 | { NULL, NULL }, | ||
5328 | }; | ||
5329 | |||
5330 | static 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 | |||
5339 | int 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 | |||
5354 | static 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 | |||
5395 | static int xc_interpose(lua_State *L) { | ||
5396 | return interpose(L, X509_CERT_CLASS); | ||
5397 | } /* xc_interpose() */ | ||
5398 | |||
5399 | |||
5400 | static 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 | |||
5409 | static 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 | |||
5422 | static 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 | |||
5436 | static 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; | ||
5451 | error: | ||
5452 | ASN1_INTEGER_free(serial); | ||
5453 | |||
5454 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:setSerial"); | ||
5455 | } /* xc_setSerial() */ | ||
5456 | |||
5457 | |||
5458 | static 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 | |||
5512 | static _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 | |||
5520 | static 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 | |||
5528 | static 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 | |||
5533 | static 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 | |||
5541 | static 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 | |||
5557 | static _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 | |||
5585 | static 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); | ||
5649 | badfmt: | ||
5650 | return INFINITY; | ||
5651 | } /* timeutc() */ | ||
5652 | |||
5653 | |||
5654 | static 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 | |||
5684 | static 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 | |||
5721 | static 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 | |||
5734 | static 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 | |||
5747 | static 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 | |||
5760 | static 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 | |||
5773 | static 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 | |||
5783 | static _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 | |||
5795 | static 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 | |||
5808 | static 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 | |||
5821 | static 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 | |||
5834 | static 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 | |||
5847 | static 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 | |||
5856 | static 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 | |||
5868 | static 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 | |||
5877 | static 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 | |||
5889 | static 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 | |||
5943 | static 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; | ||
6012 | error: | ||
6013 | BASIC_CONSTRAINTS_free(bs); | ||
6014 | |||
6015 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:setBasicConstraint"); | ||
6016 | } /* xc_setBasicConstraint() */ | ||
6017 | |||
6018 | |||
6019 | static 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 | |||
6028 | static 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 | |||
6040 | static 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 | |||
6054 | static 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; | ||
6087 | undef: | ||
6088 | return 0; | ||
6089 | error: | ||
6090 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:getExtension"); | ||
6091 | } /* xc_getExtension() */ | ||
6092 | |||
6093 | |||
6094 | static 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 | |||
6101 | static 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 | |||
6113 | static 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 | |||
6135 | static 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 | |||
6158 | done: | ||
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 | |||
6172 | static 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 | |||
6183 | static 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 | |||
6196 | static 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 | |||
6217 | static 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 | |||
6230 | static 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 | |||
6243 | static 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 | |||
6303 | static 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 | |||
6329 | static 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 | |||
6341 | static 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 | |||
6382 | static const auxL_Reg xc_metatable[] = { | ||
6383 | { "__tostring", &xc__tostring }, | ||
6384 | { "__gc", &xc__gc }, | ||
6385 | { NULL, NULL }, | ||
6386 | }; | ||
6387 | |||
6388 | |||
6389 | static const auxL_Reg xc_globals[] = { | ||
6390 | { "new", &xc_new }, | ||
6391 | { "interpose", &xc_interpose }, | ||
6392 | { NULL, NULL }, | ||
6393 | }; | ||
6394 | |||
6395 | int 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 | |||
6409 | static 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 | |||
6451 | static int xr_interpose(lua_State *L) { | ||
6452 | return interpose(L, X509_CSR_CLASS); | ||
6453 | } /* xr_interpose() */ | ||
6454 | |||
6455 | |||
6456 | static 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 | |||
6465 | static 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 | |||
6478 | static 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 | |||
6491 | static 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 | |||
6504 | static 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 | |||
6515 | static 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 | |||
6528 | static 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; | ||
6590 | error: | ||
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 | |||
6598 | static 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 | |||
6606 | static 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; | ||
6619 | error: | ||
6620 | return 0; | ||
6621 | } /* xr_getSubjectAlt() */ | ||
6622 | |||
6623 | |||
6624 | |||
6625 | static 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 | |||
6638 | static 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 | |||
6664 | static 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 | |||
6675 | static 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 | |||
6689 | static const auxL_Reg xr_metatable[] = { | ||
6690 | { "__tostring", &xr__tostring }, | ||
6691 | { "__gc", &xr__gc }, | ||
6692 | { NULL, NULL }, | ||
6693 | }; | ||
6694 | |||
6695 | |||
6696 | static const auxL_Reg xr_globals[] = { | ||
6697 | { "new", &xr_new }, | ||
6698 | { "interpose", &xr_interpose }, | ||
6699 | { NULL, NULL }, | ||
6700 | }; | ||
6701 | |||
6702 | int 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 | |||
6716 | static 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 | |||
6756 | static int xx_interpose(lua_State *L) { | ||
6757 | return interpose(L, X509_CRL_CLASS); | ||
6758 | } /* xx_interpose() */ | ||
6759 | |||
6760 | |||
6761 | static 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 | |||
6770 | static 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 | |||
6783 | static 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 | |||
6800 | static 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 | |||
6814 | static 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 | |||
6831 | static 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; | ||
6855 | error: | ||
6856 | if (time) | ||
6857 | ASN1_TIME_free(time); | ||
6858 | |||
6859 | return auxL_error(L, auxL_EOPENSSL, "x509.crl:setNextUpdate"); | ||
6860 | } /* xx_setNextUpdate() */ | ||
6861 | |||
6862 | |||
6863 | static 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 | |||
6876 | static 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 | |||
6889 | static 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; | ||
6927 | error: | ||
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 | |||
6939 | static 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 | |||
6953 | static 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; | ||
6986 | undef: | ||
6987 | return 0; | ||
6988 | error: | ||
6989 | return auxL_error(L, auxL_EOPENSSL, "x509.crl:getExtension"); | ||
6990 | } /* xx_getExtension() */ | ||
6991 | |||
6992 | |||
6993 | static 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 | |||
7000 | static 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 | |||
7013 | static 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 | |||
7026 | static 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 | |||
7044 | static 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 | |||
7070 | static 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 | |||
7081 | static 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 | |||
7101 | static const auxL_Reg xx_metatable[] = { | ||
7102 | { "__tostring", &xx__tostring }, | ||
7103 | { "__gc", &xx__gc }, | ||
7104 | { NULL, NULL }, | ||
7105 | }; | ||
7106 | |||
7107 | |||
7108 | static const auxL_Reg xx_globals[] = { | ||
7109 | { "new", &xx_new }, | ||
7110 | { "interpose", &xx_interpose }, | ||
7111 | { NULL, NULL }, | ||
7112 | }; | ||
7113 | |||
7114 | int 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 | |||
7128 | static 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; | ||
7165 | error: | ||
7166 | auxL_error(L, auxL_EOPENSSL, "sk_X509_dup"); | ||
7167 | } /* xl_dup() */ | ||
7168 | |||
7169 | |||
7170 | static 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 | |||
7180 | static int xl_interpose(lua_State *L) { | ||
7181 | return interpose(L, X509_CHAIN_CLASS); | ||
7182 | } /* xl_interpose() */ | ||
7183 | |||
7184 | |||
7185 | static 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 | |||
7204 | static 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 | |||
7233 | static 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 | |||
7242 | static 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 | |||
7254 | static const auxL_Reg xl_methods[] = { | ||
7255 | { "add", &xl_add }, | ||
7256 | { NULL, NULL }, | ||
7257 | }; | ||
7258 | |||
7259 | static const auxL_Reg xl_metatable[] = { | ||
7260 | { "__pairs", &xl__pairs }, | ||
7261 | { "__ipairs", &xl__pairs }, | ||
7262 | { "__gc", &xl__gc }, | ||
7263 | { NULL, NULL }, | ||
7264 | }; | ||
7265 | |||
7266 | static const auxL_Reg xl_globals[] = { | ||
7267 | { "new", &xl_new }, | ||
7268 | { "interpose", &xl_interpose }, | ||
7269 | { NULL, NULL }, | ||
7270 | }; | ||
7271 | |||
7272 | int 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 | |||
7286 | static 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 | |||
7296 | static 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 | |||
7306 | static int xs_interpose(lua_State *L) { | ||
7307 | return interpose(L, X509_STORE_CLASS); | ||
7308 | } /* xs_interpose() */ | ||
7309 | |||
7310 | |||
7311 | static 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 | |||
7358 | static 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 | |||
7370 | static 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 | |||
7428 | eossl: | ||
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 | |||
7436 | static 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 | |||
7448 | static const auxL_Reg xs_methods[] = { | ||
7449 | { "add", &xs_add }, | ||
7450 | { "addDefaults", &xs_addDefaults }, | ||
7451 | { "verify", &xs_verify }, | ||
7452 | { NULL, NULL }, | ||
7453 | }; | ||
7454 | |||
7455 | static const auxL_Reg xs_metatable[] = { | ||
7456 | { "__gc", &xs__gc }, | ||
7457 | { NULL, NULL }, | ||
7458 | }; | ||
7459 | |||
7460 | static const auxL_Reg xs_globals[] = { | ||
7461 | { "new", &xs_new }, | ||
7462 | { "interpose", &xs_interpose }, | ||
7463 | { NULL, NULL }, | ||
7464 | }; | ||
7465 | |||
7466 | int 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 | ||
7494 | static 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 | |||
7505 | static int stx_interpose(lua_State *L) { | ||
7506 | return interpose(L, X509_STCTX_CLASS); | ||
7507 | } /* stx_interpose() */ | ||
7508 | |||
7509 | |||
7510 | static 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 | |||
7517 | static 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 | |||
7529 | static const auxL_Reg stx_methods[] = { | ||
7530 | { "add", &stx_add }, | ||
7531 | { NULL, NULL }, | ||
7532 | }; | ||
7533 | |||
7534 | static const auxL_Reg stx_metatable[] = { | ||
7535 | { "__gc", &stx__gc }, | ||
7536 | { NULL, NULL }, | ||
7537 | }; | ||
7538 | |||
7539 | static const auxL_Reg stx_globals[] = { | ||
7540 | { "new", &stx_new }, | ||
7541 | { "interpose", &stx_interpose }, | ||
7542 | { NULL, NULL }, | ||
7543 | }; | ||
7544 | |||
7545 | int 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 | |||
7560 | static 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 | |||
7602 | error: | ||
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 | |||
7615 | static int p12_interpose(lua_State *L) { | ||
7616 | return interpose(L, PKCS12_CLASS); | ||
7617 | } /* p12_interpose() */ | ||
7618 | |||
7619 | |||
7620 | static 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 | |||
7671 | static 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 | |||
7688 | static 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 | |||
7700 | static const auxL_Reg p12_methods[] = { | ||
7701 | { "tostring", &p12__tostring }, | ||
7702 | { NULL, NULL }, | ||
7703 | }; | ||
7704 | |||
7705 | static const auxL_Reg p12_metatable[] = { | ||
7706 | { "__tostring", &p12__tostring }, | ||
7707 | { "__gc", &p12__gc }, | ||
7708 | { NULL, NULL }, | ||
7709 | }; | ||
7710 | |||
7711 | static const auxL_Reg p12_globals[] = { | ||
7712 | { "new", &p12_new }, | ||
7713 | { "interpose", &p12_interpose }, | ||
7714 | { "parse", &p12_parse }, | ||
7715 | { NULL, NULL }, | ||
7716 | }; | ||
7717 | |||
7718 | int 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 | */ | ||
7737 | static 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 | |||
7831 | static int sx_interpose(lua_State *L) { | ||
7832 | return interpose(L, SSL_CTX_CLASS); | ||
7833 | } /* sx_interpose() */ | ||
7834 | |||
7835 | |||
7836 | static 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 | |||
7846 | static 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 | |||
7855 | static 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 | |||
7865 | static 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 | |||
7877 | static 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 | |||
7891 | static 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 | |||
7904 | static 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 | |||
7923 | static 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 | |||
7940 | static 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 | |||
7950 | static 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 | |||
7967 | static 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 | |||
7989 | static 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 | |||
8002 | static 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 | ||
8048 | static 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 | ||
8077 | static 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; | ||
8132 | fatal: | ||
8133 | lua_settop(L, otop); | ||
8134 | |||
8135 | return SSL_TLSEXT_ERR_ALERT_FATAL; | ||
8136 | noack: | ||
8137 | lua_settop(L, otop); | ||
8138 | |||
8139 | return SSL_TLSEXT_ERR_NOACK; | ||
8140 | } /* sx_setAlpnSelect_cb() */ | ||
8141 | |||
8142 | static 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 | ||
8172 | static 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 | |||
8207 | done: | ||
8208 | lua_settop(L, otop); | ||
8209 | |||
8210 | return ret; | ||
8211 | } /* sx_setHostNameCallback_cb() */ | ||
8212 | |||
8213 | |||
8214 | static 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 | |||
8239 | int TLSEXT_STATUSTYPEs[] = { TLSEXT_STATUSTYPE_ocsp }; | ||
8240 | const 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 | ||
8246 | static 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 | ||
8261 | static 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 | |||
8281 | static 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 | |||
8293 | static 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 | |||
8325 | static const auxL_Reg sx_metatable[] = { | ||
8326 | { "__gc", &sx__gc }, | ||
8327 | { NULL, NULL }, | ||
8328 | }; | ||
8329 | |||
8330 | static const auxL_Reg sx_globals[] = { | ||
8331 | { "new", &sx_new }, | ||
8332 | { "interpose", &sx_interpose }, | ||
8333 | { NULL, NULL }, | ||
8334 | }; | ||
8335 | |||
8336 | static 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 | |||
8344 | static 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 | |||
8390 | int 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 | |||
8406 | static 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 | |||
8415 | static 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 | |||
8428 | static int ssl_interpose(lua_State *L) { | ||
8429 | return interpose(L, SSL_CLASS); | ||
8430 | } /* ssl_interpose() */ | ||
8431 | |||
8432 | |||
8433 | static 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 | |||
8445 | static 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 | |||
8455 | static 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 | |||
8464 | static 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 | |||
8474 | static 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 | |||
8487 | static 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 | |||
8506 | static 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 | |||
8523 | static 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 | |||
8533 | static 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 | |||
8542 | static 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 | |||
8559 | static 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 | |||
8580 | static 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 | |||
8591 | static 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 | |||
8604 | static 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 | |||
8630 | static 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 | |||
8643 | static 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 | |||
8656 | static 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 | |||
8681 | static 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 | |||
8706 | static 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 | ||
8732 | static 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 | ||
8748 | static 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 | |||
8776 | static 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 | ||
8790 | static 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 | |||
8810 | static 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 | |||
8834 | static 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 | |||
8857 | static 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 | |||
8869 | static 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 | |||
8904 | static const auxL_Reg ssl_metatable[] = { | ||
8905 | { "__gc", &ssl__gc }, | ||
8906 | { NULL, NULL }, | ||
8907 | }; | ||
8908 | |||
8909 | static const auxL_Reg ssl_globals[] = { | ||
8910 | { "new", &ssl_new }, | ||
8911 | { "interpose", &ssl_interpose }, | ||
8912 | { NULL, NULL }, | ||
8913 | }; | ||
8914 | |||
8915 | static 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 | |||
8929 | int 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 | |||
8946 | static 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 | |||
8956 | static 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 | */ | ||
8974 | static 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 | |||
8989 | static 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 | |||
9012 | static 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 | |||
9024 | static 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 | |||
9035 | static 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 | |||
9046 | static 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 | ||
9057 | static 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 | |||
9068 | static 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 | ||
9080 | static 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 | ||
9096 | static 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 | ||
9112 | static 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 | ||
9128 | static 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 | |||
9142 | static 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 | |||
9152 | static 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 | |||
9177 | static const auxL_Reg xp_metatable[] = { | ||
9178 | { "__gc", &xp__gc }, | ||
9179 | { NULL, NULL }, | ||
9180 | }; | ||
9181 | |||
9182 | static const auxL_Reg xp_globals[] = { | ||
9183 | { "new", &xp_new }, | ||
9184 | { "interpose", &xp_interpose }, | ||
9185 | { NULL, NULL }, | ||
9186 | }; | ||
9187 | |||
9188 | static 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 | |||
9197 | int 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 | |||
9212 | static 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 | |||
9223 | static 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 | |||
9235 | static int md_interpose(lua_State *L) { | ||
9236 | return interpose(L, DIGEST_CLASS); | ||
9237 | } /* md_interpose() */ | ||
9238 | |||
9239 | |||
9240 | static 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 | |||
9255 | static 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 | |||
9266 | static 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 | |||
9282 | static 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 | |||
9292 | static const auxL_Reg md_methods[] = { | ||
9293 | { "update", &md_update }, | ||
9294 | { "final", &md_final }, | ||
9295 | { NULL, NULL }, | ||
9296 | }; | ||
9297 | |||
9298 | static const auxL_Reg md_metatable[] = { | ||
9299 | { "__gc", &md__gc }, | ||
9300 | { NULL, NULL }, | ||
9301 | }; | ||
9302 | |||
9303 | static const auxL_Reg md_globals[] = { | ||
9304 | { "new", &md_new }, | ||
9305 | { "interpose", &md_interpose }, | ||
9306 | { NULL, NULL }, | ||
9307 | }; | ||
9308 | |||
9309 | int 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 | |||
9323 | static 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; | ||
9344 | eossl: | ||
9345 | return auxL_error(L, auxL_EOPENSSL, "hmac.new"); | ||
9346 | } /* hmac_new() */ | ||
9347 | |||
9348 | |||
9349 | static int hmac_interpose(lua_State *L) { | ||
9350 | return interpose(L, HMAC_CLASS); | ||
9351 | } /* hmac_interpose() */ | ||
9352 | |||
9353 | |||
9354 | static 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 | |||
9368 | static 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 | |||
9379 | static 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 | |||
9394 | static 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 | |||
9404 | static const auxL_Reg hmac_methods[] = { | ||
9405 | { "update", &hmac_update }, | ||
9406 | { "final", &hmac_final }, | ||
9407 | { NULL, NULL }, | ||
9408 | }; | ||
9409 | |||
9410 | static const auxL_Reg hmac_metatable[] = { | ||
9411 | { "__gc", &hmac__gc }, | ||
9412 | { NULL, NULL }, | ||
9413 | }; | ||
9414 | |||
9415 | static const auxL_Reg hmac_globals[] = { | ||
9416 | { "new", &hmac_new }, | ||
9417 | { "interpose", &hmac_interpose }, | ||
9418 | { NULL, NULL }, | ||
9419 | }; | ||
9420 | |||
9421 | int 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 | |||
9435 | static 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 | |||
9446 | static 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; | ||
9466 | eossl: | ||
9467 | return auxL_error(L, auxL_EOPENSSL, "cipher.new"); | ||
9468 | } /* cipher_new() */ | ||
9469 | |||
9470 | |||
9471 | static int cipher_interpose(lua_State *L) { | ||
9472 | return interpose(L, CIPHER_CLASS); | ||
9473 | } /* cipher_interpose() */ | ||
9474 | |||
9475 | |||
9476 | static 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; | ||
9502 | sslerr: | ||
9503 | return auxL_error(L, auxL_EOPENSSL, (encrypt)? "cipher:encrypt" : "cipher:decrypt"); | ||
9504 | } /* cipher_init() */ | ||
9505 | |||
9506 | |||
9507 | static int cipher_encrypt(lua_State *L) { | ||
9508 | return cipher_init(L, 1); | ||
9509 | } /* cipher_encrypt() */ | ||
9510 | |||
9511 | |||
9512 | static int cipher_decrypt(lua_State *L) { | ||
9513 | return cipher_init(L, 0); | ||
9514 | } /* cipher_decrypt() */ | ||
9515 | |||
9516 | |||
9517 | static _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 | |||
9548 | static 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; | ||
9560 | sslerr: | ||
9561 | lua_pushnil(L); | ||
9562 | auxL_pusherror(L, auxL_EOPENSSL, NULL); | ||
9563 | |||
9564 | return 2; | ||
9565 | } /* cipher_update() */ | ||
9566 | |||
9567 | |||
9568 | static 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; | ||
9591 | sslerr: | ||
9592 | lua_pushnil(L); | ||
9593 | auxL_pusherror(L, auxL_EOPENSSL, NULL); | ||
9594 | |||
9595 | return 2; | ||
9596 | } /* cipher_final() */ | ||
9597 | |||
9598 | |||
9599 | static 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 | |||
9609 | static 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 | |||
9617 | static const auxL_Reg cipher_metatable[] = { | ||
9618 | { "__gc", &cipher__gc }, | ||
9619 | { NULL, NULL }, | ||
9620 | }; | ||
9621 | |||
9622 | static const auxL_Reg cipher_globals[] = { | ||
9623 | { "new", &cipher_new }, | ||
9624 | { "interpose", &cipher_interpose }, | ||
9625 | { NULL, NULL }, | ||
9626 | }; | ||
9627 | |||
9628 | int 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 | |||
9642 | static 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 | |||
9658 | static 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 | |||
9674 | static 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 | |||
9687 | static 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 | |||
9698 | static const auxL_Reg or_methods[] = { | ||
9699 | { "tostring", &or_tostring }, | ||
9700 | { "toPEM", &or_toPEM }, | ||
9701 | { "getBasic", &or_getBasic }, | ||
9702 | { NULL, NULL }, | ||
9703 | }; | ||
9704 | |||
9705 | static const auxL_Reg or_metatable[] = { | ||
9706 | { "__tostring", &or_tostring }, | ||
9707 | { "__gc", &or__gc }, | ||
9708 | { NULL, NULL }, | ||
9709 | }; | ||
9710 | |||
9711 | static const auxL_Reg or_globals[] = { | ||
9712 | { NULL, NULL }, | ||
9713 | }; | ||
9714 | |||
9715 | int 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 | |||
9729 | static 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 | |||
9749 | static 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 | |||
9761 | static const auxL_Reg ob_methods[] = { | ||
9762 | { "verify", &ob_verify }, | ||
9763 | { NULL, NULL }, | ||
9764 | }; | ||
9765 | |||
9766 | static const auxL_Reg ob_metatable[] = { | ||
9767 | { "__gc", &ob__gc }, | ||
9768 | { NULL, NULL }, | ||
9769 | }; | ||
9770 | |||
9771 | static const auxL_Reg ob_globals[] = { | ||
9772 | { NULL, NULL }, | ||
9773 | }; | ||
9774 | |||
9775 | static 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 | |||
9787 | int 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 | |||
9802 | struct randL_state { | ||
9803 | pid_t pid; | ||
9804 | }; /* struct randL_state */ | ||
9805 | |||
9806 | static 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 | |||
9818 | static 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; | ||
9907 | syserr: | ||
9908 | error = errno; | ||
9909 | error:; | ||
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 | |||
9954 | static void randL_checkpid(struct randL_state *st) { | ||
9955 | if (st->pid != getpid()) | ||
9956 | (void)randL_stir(st, 16); | ||
9957 | } /* randL_checkpid() */ | ||
9958 | |||
9959 | |||
9960 | static 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 | |||
9977 | static 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 | |||
9993 | static 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 | |||
10018 | static int rand_ready(lua_State *L) { | ||
10019 | lua_pushboolean(L, RAND_status() == 1); | ||
10020 | |||
10021 | return 1; | ||
10022 | } /* rand_ready() */ | ||
10023 | |||
10024 | |||
10025 | static 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 | */ | ||
10100 | static 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 | |||
10129 | static 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 | |||
10138 | int 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 | |||
10156 | static 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 | |||
10165 | static 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 | |||
10180 | static 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 | |||
10186 | int 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 | |||
10200 | static struct { | ||
10201 | pthread_mutex_t *lock; | ||
10202 | int nlock; | ||
10203 | } mt_state; | ||
10204 | |||
10205 | static 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 | |||
10222 | static 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 | |||
10244 | static 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; | ||
10293 | epilog: | ||
10294 | pthread_mutex_unlock(&mutex); | ||
10295 | |||
10296 | return error; | ||
10297 | } /* mt_init() */ | ||
10298 | |||
10299 | |||
10300 | static 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 @@ | |||
1 | local ctx = require"_openssl.cipher" | ||
2 | |||
3 | return 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 @@ | |||
1 | local ctx = require"_openssl.des" | ||
2 | |||
3 | return 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 @@ | |||
1 | local ctx = require"_openssl.digest" | ||
2 | |||
3 | return 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 @@ | |||
1 | local ctx = require"_openssl.hmac" | ||
2 | |||
3 | return 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 @@ | |||
1 | local ob = require "_openssl.ocsp.basic" | ||
2 | |||
3 | return ob | ||
diff --git a/src/openssl.ocsp.response.lua b/src/openssl.ocsp.response.lua new file mode 100644 index 0000000..2226096 --- /dev/null +++ b/src/openssl.ocsp.response.lua | |||
@@ -0,0 +1,3 @@ | |||
1 | local ocsp_response = require "_openssl.ocsp.response" | ||
2 | |||
3 | return 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 @@ | |||
1 | local pkey = require"_openssl.pkey" | ||
2 | |||
3 | return 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 | ||
2 | return 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 @@ | |||
1 | local ctx = require"_openssl.rand" | ||
2 | |||
3 | return 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 @@ | |||
1 | local ctx = require"_openssl.ssl.context" | ||
2 | |||
3 | local pack = table.pack or function(...) return { n = select("#", ...); ... } end | ||
4 | |||
5 | -- Allow passing a vararg of ciphers, or an array | ||
6 | local 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) | ||
14 | end) | ||
15 | |||
16 | return 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 @@ | |||
1 | local ctx = require"_openssl.ssl" | ||
2 | |||
3 | return 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 @@ | |||
1 | local altname = require"_openssl.x509.altname" | ||
2 | local auxlib = require"openssl.auxlib" | ||
3 | |||
4 | altname.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, ", ") | ||
12 | end) | ||
13 | |||
14 | return 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 @@ | |||
1 | local chain = require"_openssl.x509.chain" | ||
2 | |||
3 | return 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 @@ | |||
1 | local x509 = require"_openssl.x509.cert" | ||
2 | |||
3 | return 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 @@ | |||
1 | local name = require"_openssl.x509.name" | ||
2 | local auxlib = require"openssl.auxlib" | ||
3 | |||
4 | name.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, ", ") | ||
12 | end) | ||
13 | |||
14 | return 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 @@ | |||
1 | local store = require"_openssl.x509.store" | ||
2 | |||
3 | return 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') | |||