diff options
author | William Ahern <william@server.local> | 2013-12-09 20:56:25 -0800 |
---|---|---|
committer | William Ahern <william@server.local> | 2013-12-09 20:56:25 -0800 |
commit | d4aa420319bff15a6f84f679c6374dda7cf1b0f2 (patch) | |
tree | b716502f27733e5dd9d2e45715a00bf88586e12e /src | |
parent | e42cc7815ff3c948c4ab4e2782da2a2cb4f476bf (diff) | |
download | luaossl-d4aa420319bff15a6f84f679c6374dda7cf1b0f2.tar.gz luaossl-d4aa420319bff15a6f84f679c6374dda7cf1b0f2.tar.bz2 luaossl-d4aa420319bff15a6f84f679c6374dda7cf1b0f2.zip |
move newly split files into src/ directory
Diffstat (limited to 'src')
-rw-r--r-- | src/GNUmakefile | 214 | ||||
-rw-r--r-- | src/Makefile | 7 | ||||
-rw-r--r-- | src/compat52.h | 152 | ||||
-rw-r--r-- | src/openssl.bignum.lua | 3 | ||||
-rw-r--r-- | src/openssl.c | 3929 | ||||
-rw-r--r-- | src/openssl.cipher.lua | 3 | ||||
-rw-r--r-- | src/openssl.digest.lua | 3 | ||||
-rw-r--r-- | src/openssl.hmac.lua | 3 | ||||
-rw-r--r-- | src/openssl.pubkey.lua | 4 | ||||
-rw-r--r-- | src/openssl.rand.lua | 3 | ||||
-rw-r--r-- | src/openssl.ssl.context.lua | 3 | ||||
-rw-r--r-- | src/openssl.ssl.lua | 3 | ||||
-rw-r--r-- | src/openssl.x509.altname.lua | 13 | ||||
-rw-r--r-- | src/openssl.x509.chain.lua | 3 | ||||
-rw-r--r-- | src/openssl.x509.lua | 3 | ||||
-rw-r--r-- | src/openssl.x509.name.lua | 13 | ||||
-rw-r--r-- | src/openssl.x509.store.lua | 3 |
17 files changed, 4362 insertions, 0 deletions
diff --git a/src/GNUmakefile b/src/GNUmakefile new file mode 100644 index 0000000..fcf79a6 --- /dev/null +++ b/src/GNUmakefile | |||
@@ -0,0 +1,214 @@ | |||
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 | OS_$(d) = $(shell $(d)/../mk/vendor.os) | ||
20 | CC_$(d) = $(shell $(d)/../mk/vendor.cc) | ||
21 | LUAPATH_$(d) = $(shell env CC="$(CC)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(<D)/../mk/lua.path -krxm3 -I$(DESTDIR)$(includedir) -I/usr/include -I/usr/local/include -P$(DESTDIR)$(bindir) -P$(bindir) -L$(DESTDIR)$(libdir) -L$(libdir) -v$(1) $(2)) | ||
22 | |||
23 | CPPFLAGS_$(d) = $(CPPFLAGS_$(abspath $(@D)/../..)) | ||
24 | CFLAGS_$(d) = $(CFLAGS_$(abspath $(@D)/../..)) | ||
25 | LDFLAGS_$(d) = $(LDFLAGS_$(abspath $(@D)/../..)) | ||
26 | SOFLAGS_$(d) = $(SOFLAGS_$(abspath $(@D)/../..)) | ||
27 | |||
28 | ifeq ($(CC_$(d)), sunpro) | ||
29 | CPPFLAGS_$(d) += -DOPENSSL_NO_EC | ||
30 | endif | ||
31 | |||
32 | LDFLAGS_$(d) += -lssl -lcrypto | ||
33 | |||
34 | # | ||
35 | # C O M P I L A T I O N R U L E S | ||
36 | # | ||
37 | |||
38 | define BUILD_$(d) | ||
39 | |||
40 | .SECONDARY: liblua$(1)-openssl openssl$(1) | ||
41 | |||
42 | $$(d)/$(1)/openssl.so: $$(d)/$(1)/openssl.o | ||
43 | $$(CC) -o $$@ $$^ $$(SOFLAGS_$$(abspath $$(@D)/..)) $$(SOFLAGS) $$(LDFLAGS_$$(abspath $$(@D)/..)) $$(LDFLAGS) | ||
44 | |||
45 | $$(d)/$(1)/openssl.o: $$(d)/openssl.c $$(d)/compat52.h | ||
46 | test "$$(notdir $$(@D))" = "$$(call LUAPATH_$$(<D), $$(notdir $$(@D)), version)" | ||
47 | $$(MKDIR) -p $$(@D) | ||
48 | $$(CC) $$(CFLAGS_$$(<D)) $$(CFLAGS) $$(call LUAPATH_$$(<D), $$(notdir $$(@D)), cppflags) $$(CPPFLAGS_$$(<D)) $$(CPPFLAGS) -c -o $$@ $$< | ||
49 | |||
50 | liblua$(1)-openssl openssl$(1): $$(d)/$(1)/openssl.so | ||
51 | |||
52 | endef # BUILD_$(d) | ||
53 | |||
54 | $(eval $(call BUILD_$(d),5.1)) | ||
55 | |||
56 | $(eval $(call BUILD_$(d),5.2)) | ||
57 | |||
58 | ifneq "$(filter $(abspath $(d)/..)/%, $(abspath $(firstword $(MAKEFILE_LIST))))" "" | ||
59 | .SECONDARY: all5.1 all5.2 all | ||
60 | |||
61 | all5.1: liblua5.1-openssl | ||
62 | |||
63 | all5.2: liblua5.2-openssl | ||
64 | |||
65 | all: all5.1 all5.2 | ||
66 | |||
67 | endif | ||
68 | |||
69 | |||
70 | # | ||
71 | # I N S T A L L & U N I N S T A L L R U L E S | ||
72 | # | ||
73 | define INSTALL_$(d) | ||
74 | |||
75 | LUAC$(1)_$(d) = $$(or $$(call LUAPATH_$(d), $(1), luac), true) | ||
76 | |||
77 | MODS$(1)_$(d) = \ | ||
78 | $$(DESTDIR)$(2)/_openssl.so \ | ||
79 | $$(DESTDIR)$(3)/openssl/bignum.lua \ | ||
80 | $$(DESTDIR)$(3)/openssl/pubkey.lua \ | ||
81 | $$(DESTDIR)$(3)/openssl/x509.lua \ | ||
82 | $$(DESTDIR)$(3)/openssl/x509/name.lua \ | ||
83 | $$(DESTDIR)$(3)/openssl/x509/altname.lua \ | ||
84 | $$(DESTDIR)$(3)/openssl/x509/chain.lua \ | ||
85 | $$(DESTDIR)$(3)/openssl/x509/store.lua \ | ||
86 | $$(DESTDIR)$(3)/openssl/ssl/context.lua \ | ||
87 | $$(DESTDIR)$(3)/openssl/ssl.lua \ | ||
88 | $$(DESTDIR)$(3)/openssl/digest.lua \ | ||
89 | $$(DESTDIR)$(3)/openssl/hmac.lua \ | ||
90 | $$(DESTDIR)$(3)/openssl/cipher.lua \ | ||
91 | $$(DESTDIR)$(3)/openssl/rand.lua | ||
92 | |||
93 | .SECONDARY: liblua$(1)-openssl-install openssl$(1)-install | ||
94 | |||
95 | $$(DESTDIR)$(2)/_openssl.so: $$(d)/$(1)/openssl.so | ||
96 | $$(MKDIR) -p $$(@D) | ||
97 | $$(CP) -p $$< $$@ | ||
98 | |||
99 | $$(DESTDIR)$(3)/openssl/%.lua: $$(d)/openssl.%.lua | ||
100 | $$(LUAC$(1)_$(d)) -p $$< | ||
101 | $$(MKDIR) -p $$(@D) | ||
102 | $$(CP) -p $$< $$@ | ||
103 | |||
104 | $$(DESTDIR)$(3)/openssl/x509/%.lua: $$(d)/openssl.x509.%.lua | ||
105 | $$(LUAC$(1)_$(d)) -p $$< | ||
106 | $$(MKDIR) -p $$(@D) | ||
107 | $$(CP) -p $$< $$@ | ||
108 | |||
109 | $$(DESTDIR)$(3)/openssl/ssl/%.lua: $$(d)/openssl.ssl.%.lua | ||
110 | $$(LUAC$(1)_$(d)) -p $$< | ||
111 | $$(MKDIR) -p $$(@D) | ||
112 | $$(CP) -p $$< $$@ | ||
113 | |||
114 | $$(DESTDIR)$(3)/openssl/ssl/%.lua: $$(d)/openssl.ssl.%.lua | ||
115 | $$(LUAC$(1)_$(d)) -p $$< | ||
116 | $$(MKDIR) -p $$(@D) | ||
117 | $$(CP) -p $$< $$@ | ||
118 | |||
119 | liblua$(1)-openssl-install openssl$(1)-install: $$(MODS$(1)_$$(d)) | ||
120 | |||
121 | .PHONY: liblua$(1)-openssl-uninstall openssl$(1)-uninstall | ||
122 | |||
123 | liblua$(1)-openssl-uninstall openssl$(1)-uninstall: | ||
124 | $$(RM) -f $$(MODS$(1)_$(d)) | ||
125 | -$$(RMDIR) $$(DESTDIR)$(3)/openssl/x509 | ||
126 | -$$(RMDIR) $$(DESTDIR)$(3)/openssl/ssl | ||
127 | -$$(RMDIR) $$(DESTDIR)$(3)/openssl | ||
128 | |||
129 | endef # INSTALL_$(d) | ||
130 | |||
131 | $(eval $(call INSTALL_$(d),5.1,$$(lua51cpath),$$(lua51path))) | ||
132 | |||
133 | $(eval $(call INSTALL_$(d),5.2,$$(lua52cpath),$$(lua52path))) | ||
134 | |||
135 | ifneq "$(filter $(abspath $(d)/..)/%, $(abspath $(firstword $(MAKEFILE_LIST))))" "" | ||
136 | .SECONDARY: install5.1 install5.2 install | ||
137 | |||
138 | install5.1: liblua5.1-openssl-install | ||
139 | |||
140 | install5.2: liblua5.2-openssl-install | ||
141 | |||
142 | install: install5.1 install5.2 | ||
143 | |||
144 | .PHONY: uninstall5.1 uninstall5.2 uninstall | ||
145 | |||
146 | uninstall5.1: liblua5.1-openssl-uninstall | ||
147 | |||
148 | uninstall5.2: liblua5.2-openssl-uninstall | ||
149 | |||
150 | uninstall: uninstall5.1 uninstall5.2 | ||
151 | |||
152 | endif | ||
153 | |||
154 | |||
155 | # | ||
156 | # C L E A N R U L E S | ||
157 | # | ||
158 | .PHONY: $(d)/clean $(d)/clean~ clean clean~ | ||
159 | |||
160 | $(d)/clean: | ||
161 | $(RM) -fr $(@D)/*.so $(@D)/*.o $(@D)/*.dSYM $(@D)/5.1 $(@D)/5.2 | ||
162 | |||
163 | $(d)/clean~: $(d)/clean | ||
164 | $(RM) -f $(@D)/*~ | ||
165 | |||
166 | clean: $(d)/clean | ||
167 | |||
168 | clean~: $(d)/clean~ | ||
169 | |||
170 | |||
171 | # | ||
172 | # H E L P R U L E S | ||
173 | # | ||
174 | .PHONY: $(d)/help help | ||
175 | |||
176 | $(d)/help: | ||
177 | @echo | ||
178 | @echo "ext/ targets:" | ||
179 | @echo "" | ||
180 | @echo " all - build all binary targets" | ||
181 | @echo "openssl - invokes openssl5.1 and openssl5.2" | ||
182 | @echo "openssl5.1 - build 5.1/openssl.so" | ||
183 | @echo "openssl5.2 - build 5.2/openssl.so" | ||
184 | @echo "install - invokes install5.1 and install5.2" | ||
185 | @echo "install5.1 - install openssl Lua 5.1 modules" | ||
186 | @echo "install5.2 - install openssl Lua 5.2 modules" | ||
187 | @echo "uninstall - invokes uninstall5.1 and uninstall5.2" | ||
188 | @echo "uninstall5.1 - uninstall openssl Lua 5.1 modules" | ||
189 | @echo "uninstall5.2 - uninstall openssl Lua 5.2 modules" | ||
190 | @echo " clean - rm binary targets, object files, debugging symbols, etc" | ||
191 | @echo " clean~ - clean + rm *~" | ||
192 | @echo " help - echo this help message" | ||
193 | @echo "" | ||
194 | @echo "Some important Make variables:" | ||
195 | @echo "" | ||
196 | @echo " prefix - path to install root" | ||
197 | @echo ' lua51path - install path for Lua 5.1 modules ($$(lua51path))' | ||
198 | @echo 'lua51cpath - install path for Lua 5.1 C modules ($$(lua51cpath))' | ||
199 | @echo ' lua52path - install path for Lua 5.1 modules ($$(lua51path))' | ||
200 | @echo 'lua52cpath - install path for Lua 5.1 C modules ($$(lua51cpath))' | ||
201 | @echo "" | ||
202 | @echo "(NOTE: all the common GNU-style paths are supported, including" | ||
203 | @echo "prefix, bindir, libdir, datadir, includedir, and DESTDIR.)" | ||
204 | @echo "" | ||
205 | @echo "Report bugs to <william@25thandClement.com>" | ||
206 | |||
207 | help: $(d)/help | ||
208 | |||
209 | |||
210 | endif # include guard | ||
211 | |||
212 | # non-recursive epilogue | ||
213 | d := $(dirstack_$(sp)) | ||
214 | 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..96ec9b2 --- /dev/null +++ b/src/compat52.h | |||
@@ -0,0 +1,152 @@ | |||
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 | #if LUA_VERSION_NUM < 502 | ||
27 | |||
28 | #define LUA_OK 0 | ||
29 | |||
30 | |||
31 | static void luaL_setmetatable(lua_State *L, const char *tname) { | ||
32 | luaL_getmetatable(L, tname); | ||
33 | lua_setmetatable(L, -2); | ||
34 | } /* luaL_setmetatable() */ | ||
35 | |||
36 | |||
37 | static int lua_absindex(lua_State *L, int idx) { | ||
38 | return (idx > 0 || idx <= LUA_REGISTRYINDEX)? idx : lua_gettop(L) + idx + 1; | ||
39 | } /* lua_absindex() */ | ||
40 | |||
41 | |||
42 | static void *luaL_testudata(lua_State *L, int arg, const char *tname) { | ||
43 | void *p = lua_touserdata(L, arg); | ||
44 | int eq; | ||
45 | |||
46 | if (!p || !lua_getmetatable(L, arg)) | ||
47 | return 0; | ||
48 | |||
49 | luaL_getmetatable(L, tname); | ||
50 | eq = lua_rawequal(L, -2, -1); | ||
51 | lua_pop(L, 2); | ||
52 | |||
53 | return (eq)? p : 0; | ||
54 | } /* luaL_testudate() */ | ||
55 | |||
56 | |||
57 | static void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) { | ||
58 | int i, t = lua_absindex(L, -1 - nup); | ||
59 | |||
60 | for (; l->name; l++) { | ||
61 | for (i = 0; i < nup; i++) | ||
62 | lua_pushvalue(L, -nup); | ||
63 | lua_pushcclosure(L, l->func, nup); | ||
64 | lua_setfield(L, t, l->name); | ||
65 | } | ||
66 | |||
67 | lua_pop(L, nup); | ||
68 | } /* luaL_setfuncs() */ | ||
69 | |||
70 | |||
71 | #define luaL_newlibtable(L, l) \ | ||
72 | lua_createtable(L, 0, (sizeof (l) / sizeof *(l)) - 1) | ||
73 | |||
74 | #define luaL_newlib(L, l) \ | ||
75 | (luaL_newlibtable((L), (l)), luaL_setfuncs((L), (l), 0)) | ||
76 | |||
77 | |||
78 | static void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int glb) { | ||
79 | lua_pushcfunction(L, openf); | ||
80 | lua_pushstring(L, modname); | ||
81 | lua_call(L, 1, 1); | ||
82 | |||
83 | lua_getglobal(L, "package"); | ||
84 | lua_getfield(L, -1, "loaded"); | ||
85 | lua_pushvalue(L, -3); | ||
86 | lua_setfield(L, -2, modname); | ||
87 | |||
88 | lua_pop(L, 2); | ||
89 | |||
90 | if (glb) { | ||
91 | lua_pushvalue(L, -1); | ||
92 | lua_setglobal(L, modname); | ||
93 | } | ||
94 | } /* luaL_requiref() */ | ||
95 | |||
96 | |||
97 | #define lua_resume(L, from, nargs) lua_resume((L), (nargs)) | ||
98 | |||
99 | |||
100 | static void lua_rawgetp(lua_State *L, int index, const void *p) { | ||
101 | index = lua_absindex(L, index); | ||
102 | lua_pushlightuserdata(L, (void *)p); | ||
103 | lua_rawget(L, index); | ||
104 | } /* lua_rawgetp() */ | ||
105 | |||
106 | static void lua_rawsetp(lua_State *L, int index, const void *p) { | ||
107 | index = lua_absindex(L, index); | ||
108 | lua_pushlightuserdata(L, (void *)p); | ||
109 | lua_pushvalue(L, -2); | ||
110 | lua_rawset(L, index); | ||
111 | lua_pop(L, 1); | ||
112 | } /* lua_rawsetp() */ | ||
113 | |||
114 | |||
115 | #ifndef LUA_UNSIGNED | ||
116 | #define LUA_UNSIGNED unsigned | ||
117 | #endif | ||
118 | |||
119 | typedef LUA_UNSIGNED lua_Unsigned; | ||
120 | |||
121 | |||
122 | static void lua_pushunsigned(lua_State *L, lua_Unsigned n) { | ||
123 | lua_pushnumber(L, (lua_Number)n); | ||
124 | } /* lua_pushunsigned() */ | ||
125 | |||
126 | static lua_Unsigned luaL_checkunsigned(lua_State *L, int arg) { | ||
127 | return (lua_Unsigned)luaL_checknumber(L, arg); | ||
128 | } /* luaL_checkunsigned() */ | ||
129 | |||
130 | |||
131 | static lua_Unsigned luaL_optunsigned(lua_State *L, int arg, lua_Unsigned def) { | ||
132 | return (lua_Unsigned)luaL_optnumber(L, arg, (lua_Number)def); | ||
133 | } /* luaL_optunsigned() */ | ||
134 | |||
135 | |||
136 | #ifndef LUA_FILEHANDLE /* Not defined by earlier LuaJIT releases */ | ||
137 | #define LUA_FILEHANDLE "FILE*" | ||
138 | #endif | ||
139 | |||
140 | /* | ||
141 | * Lua 5.1 userdata is a simple FILE *, while LuaJIT is a struct with the | ||
142 | * first member a FILE *, similar to Lua 5.2. | ||
143 | */ | ||
144 | typedef struct luaL_Stream { | ||
145 | FILE *f; | ||
146 | } luaL_Stream; | ||
147 | |||
148 | |||
149 | #define lua_rawlen(...) lua_objlen(__VA_ARGS__) | ||
150 | |||
151 | |||
152 | #endif /* LUA_VERSION_NUM < 502 */ | ||
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..c8af43d --- /dev/null +++ b/src/openssl.c | |||
@@ -0,0 +1,3929 @@ | |||
1 | /* ========================================================================== | ||
2 | * openssl.c - Lua OpenSSL | ||
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 | #ifndef L_OPENSSL_H | ||
27 | #define L_OPENSSH_H | ||
28 | |||
29 | #include <limits.h> /* INT_MAX INT_MIN */ | ||
30 | #include <string.h> /* memset(3) */ | ||
31 | #include <strings.h> /* strcasecmp(3) */ | ||
32 | #include <math.h> /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */ | ||
33 | #include <time.h> /* struct tm time_t strptime(3) */ | ||
34 | |||
35 | #include <sys/types.h> | ||
36 | #include <sys/stat.h> /* struct stat stat(2) */ | ||
37 | #include <sys/socket.h> /* AF_INET AF_INET6 */ | ||
38 | |||
39 | #include <netinet/in.h> /* struct in_addr struct in6_addr */ | ||
40 | #include <arpa/inet.h> /* inet_pton(3) */ | ||
41 | |||
42 | #include <openssl/err.h> | ||
43 | #include <openssl/bn.h> | ||
44 | #include <openssl/asn1.h> | ||
45 | #include <openssl/x509.h> | ||
46 | #include <openssl/x509v3.h> | ||
47 | #include <openssl/evp.h> | ||
48 | #include <openssl/pem.h> | ||
49 | #include <openssl/ssl.h> | ||
50 | #include <openssl/hmac.h> | ||
51 | #include <openssl/rand.h> | ||
52 | |||
53 | #include <lua.h> | ||
54 | #include <lualib.h> | ||
55 | #include <lauxlib.h> | ||
56 | |||
57 | #if LUA_VERSION_NUM < 502 | ||
58 | #include "compat52.h" | ||
59 | #endif | ||
60 | |||
61 | #define BIGNUM_CLASS "BIGNUM*" | ||
62 | #define PUBKEY_CLASS "EVP_PKEY*" | ||
63 | #define X509_NAME_CLASS "X509_NAME*" | ||
64 | #define X509_GENS_CLASS "GENERAL_NAMES*" | ||
65 | #define X509_CERT_CLASS "X509*" | ||
66 | #define X509_CHAIN_CLASS "STACK_OF(X509)*" | ||
67 | #define X509_CSR_CLASS "X509_REQ*" | ||
68 | #define X509_STORE_CLASS "X509_STORE*" | ||
69 | #define X509_STCTX_CLASS "X509_STORE_CTX*" | ||
70 | #define SSL_CTX_CLASS "SSL_CTX*" | ||
71 | #define SSL_CLASS "SSL*" | ||
72 | #define DIGEST_CLASS "EVP_MD_CTX" /* not a pointer */ | ||
73 | #define HMAC_CLASS "HMAC_CTX" /* not a pointer */ | ||
74 | #define CIPHER_CLASS "EVP_CIPHER_CTX" /* not a pointer */ | ||
75 | |||
76 | |||
77 | #define countof(a) (sizeof (a) / sizeof *(a)) | ||
78 | #define endof(a) (&(a)[countof(a)]) | ||
79 | |||
80 | #define CLAMP(i, min, max) (((i) < (min))? (min) : ((i) > (max))? (max) : (i)) | ||
81 | |||
82 | #undef MIN | ||
83 | #define MIN(a, b) (((a) < (b))? (a) : (b)) | ||
84 | |||
85 | #define stricmp(a, b) strcasecmp((a), (b)) | ||
86 | #define strieq(a, b) (!stricmp((a), (b))) | ||
87 | |||
88 | #define SAY_(file, func, line, fmt, ...) \ | ||
89 | fprintf(stderr, "%s:%d: " fmt "%s", __func__, __LINE__, __VA_ARGS__) | ||
90 | |||
91 | #define SAY(...) SAY_(__FILE__, __func__, __LINE__, __VA_ARGS__, "\n") | ||
92 | |||
93 | #define HAI SAY("hai") | ||
94 | |||
95 | |||
96 | static void *prepudata(lua_State *L, size_t size, const char *tname, int (*gc)(lua_State *)) { | ||
97 | void *p = memset(lua_newuserdata(L, size), 0, size); | ||
98 | |||
99 | if (tname) { | ||
100 | luaL_setmetatable(L, tname); | ||
101 | } else { | ||
102 | lua_newtable(L); | ||
103 | lua_pushcfunction(L, gc); | ||
104 | lua_setfield(L, -2, "__gc"); | ||
105 | lua_setmetatable(L, -2); | ||
106 | } | ||
107 | |||
108 | return p; | ||
109 | } /* prepudata() */ | ||
110 | |||
111 | |||
112 | static void *prepsimple(lua_State *L, const char *tname, int (*gc)(lua_State *)) { | ||
113 | void **p = prepudata(L, sizeof (void *), tname, gc); | ||
114 | return p; | ||
115 | } /* prepsimple() */ | ||
116 | |||
117 | #define prepsimple_(a, b, c, ...) prepsimple((a), (b), (c)) | ||
118 | #define prepsimple(...) prepsimple_(__VA_ARGS__, 0) | ||
119 | |||
120 | |||
121 | static void *checksimple(lua_State *L, int index, const char *tname) { | ||
122 | void **p; | ||
123 | |||
124 | if (tname) { | ||
125 | p = luaL_checkudata(L, index, tname); | ||
126 | } else { | ||
127 | luaL_checktype(L, index, LUA_TUSERDATA); | ||
128 | p = lua_touserdata(L, index); | ||
129 | } | ||
130 | |||
131 | return *p; | ||
132 | } /* checksimple() */ | ||
133 | |||
134 | |||
135 | static void *testsimple(lua_State *L, int index, const char *tname) { | ||
136 | void **p; | ||
137 | |||
138 | if (tname) { | ||
139 | p = luaL_testudata(L, index, tname); | ||
140 | } else { | ||
141 | luaL_checktype(L, index, LUA_TUSERDATA); | ||
142 | p = lua_touserdata(L, index); | ||
143 | } | ||
144 | |||
145 | return (p)? *p : (void *)0; | ||
146 | } /* testsimple() */ | ||
147 | |||
148 | |||
149 | static const char *pusherror(lua_State *L, const char *fun) { | ||
150 | unsigned long code; | ||
151 | const char *path, *file; | ||
152 | int line; | ||
153 | char txt[256]; | ||
154 | |||
155 | code = ERR_get_error_line(&path, &line); | ||
156 | |||
157 | if ((file = strrchr(path, '/'))) | ||
158 | ++file; | ||
159 | else | ||
160 | file = path; | ||
161 | |||
162 | ERR_clear_error(); | ||
163 | |||
164 | ERR_error_string_n(code, txt, sizeof txt); | ||
165 | |||
166 | if (fun) | ||
167 | return lua_pushfstring(L, "%s: %s:%d:%s", fun, file, line, txt); | ||
168 | else | ||
169 | return lua_pushfstring(L, "%s:%d:%s", file, line, txt); | ||
170 | } /* pusherror() */ | ||
171 | |||
172 | |||
173 | static int throwssl(lua_State *L, const char *fun) { | ||
174 | pusherror(L, fun); | ||
175 | |||
176 | return lua_error(L); | ||
177 | } /* throwssl() */ | ||
178 | |||
179 | |||
180 | static int interpose(lua_State *L, const char *mt) { | ||
181 | luaL_getmetatable(L, mt); | ||
182 | |||
183 | if (!strncmp("__", luaL_checkstring(L, 1), 2)) | ||
184 | lua_pushvalue(L, -1); | ||
185 | else | ||
186 | lua_getfield(L, -1, "__index"); | ||
187 | |||
188 | lua_pushvalue(L, -4); /* push method name */ | ||
189 | lua_gettable(L, -2); /* push old method */ | ||
190 | |||
191 | lua_pushvalue(L, -5); /* push method name */ | ||
192 | lua_pushvalue(L, -5); /* push new method */ | ||
193 | lua_settable(L, -4); /* replace old method */ | ||
194 | |||
195 | return 1; /* return old method */ | ||
196 | } /* interpose() */ | ||
197 | |||
198 | |||
199 | static void addclass(lua_State *L, const char *name, const luaL_Reg *methods, const luaL_Reg *metamethods) { | ||
200 | if (luaL_newmetatable(L, name)) { | ||
201 | luaL_setfuncs(L, metamethods, 0); | ||
202 | lua_newtable(L); | ||
203 | luaL_setfuncs(L, methods, 0); | ||
204 | lua_setfield(L, -2, "__index"); | ||
205 | lua_pop(L, 1); | ||
206 | } | ||
207 | } /* addclass() */ | ||
208 | |||
209 | |||
210 | static int checkoption(struct lua_State *L, int index, const char *def, const char *opts[]) { | ||
211 | const char *opt = (def)? luaL_optstring(L, index, def) : luaL_checkstring(L, index); | ||
212 | int i; | ||
213 | |||
214 | for (i = 0; opts[i]; i++) { | ||
215 | if (strieq(opts[i], opt)) | ||
216 | return i; | ||
217 | } | ||
218 | |||
219 | return luaL_argerror(L, index, lua_pushfstring(L, "invalid option %s", opt)); | ||
220 | } /* checkoption() */ | ||
221 | |||
222 | |||
223 | static _Bool getfield(lua_State *L, int index, const char *k) { | ||
224 | lua_getfield(L, index, k); | ||
225 | |||
226 | if (lua_isnil(L, -1)) { | ||
227 | lua_pop(L, 1); | ||
228 | |||
229 | return 0; | ||
230 | } else { | ||
231 | return 1; | ||
232 | } | ||
233 | } /* getfield() */ | ||
234 | |||
235 | |||
236 | static _Bool loadfield(lua_State *L, int index, const char *k, int type, void *p) { | ||
237 | if (!getfield(L, index, k)) | ||
238 | return 0; | ||
239 | |||
240 | switch (type) { | ||
241 | case LUA_TSTRING: | ||
242 | *(const char **)p = luaL_checkstring(L, -1); | ||
243 | break; | ||
244 | case LUA_TNUMBER: | ||
245 | *(lua_Number *)p = luaL_checknumber(L, -1); | ||
246 | break; | ||
247 | default: | ||
248 | luaL_error(L, "loadfield(type=%d): invalid type", type); | ||
249 | break; | ||
250 | } /* switch() */ | ||
251 | |||
252 | lua_pop(L, 1); /* table keeps reference */ | ||
253 | |||
254 | return 1; | ||
255 | } /* loadfield() */ | ||
256 | |||
257 | |||
258 | static const char *pushnid(lua_State *L, int nid) { | ||
259 | const char *txt; | ||
260 | ASN1_OBJECT *obj; | ||
261 | char buf[256]; | ||
262 | int len; | ||
263 | |||
264 | if ((txt = OBJ_nid2sn(nid)) || (txt = OBJ_nid2ln(nid))) { | ||
265 | lua_pushstring(L, txt); | ||
266 | } else { | ||
267 | if (!(obj = OBJ_nid2obj(nid))) | ||
268 | luaL_error(L, "%d: unknown ASN.1 NID", nid); | ||
269 | |||
270 | if (-1 == (len = OBJ_obj2txt(buf, sizeof buf, obj, 1))) | ||
271 | luaL_error(L, "%d: invalid ASN.1 NID", nid); | ||
272 | |||
273 | lua_pushlstring(L, buf, len); | ||
274 | } | ||
275 | |||
276 | return lua_tostring(L, -1); | ||
277 | } /* pushnid() */ | ||
278 | |||
279 | |||
280 | static void initall(lua_State *L); | ||
281 | |||
282 | |||
283 | /* | ||
284 | * BIGNUM - openssl.bignum | ||
285 | * | ||
286 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
287 | |||
288 | static BIGNUM *bn_push(lua_State *L) { | ||
289 | BIGNUM **ud = prepsimple(L, BIGNUM_CLASS); | ||
290 | |||
291 | if (!(*ud = BN_new())) | ||
292 | throwssl(L, "bignum.new"); | ||
293 | |||
294 | return *ud; | ||
295 | } /* bn_push() */ | ||
296 | |||
297 | |||
298 | #define checkbig_(a, b, c, ...) checkbig((a), (b), (c)) | ||
299 | #define checkbig(...) checkbig_(__VA_ARGS__, &(_Bool){ 0 }) | ||
300 | |||
301 | static BIGNUM *(checkbig)(lua_State *, int, _Bool *); | ||
302 | |||
303 | static int bn_new(lua_State *L) { | ||
304 | int i, n; | ||
305 | |||
306 | if ((n = lua_gettop(L)) > 0) { | ||
307 | for (i = 1; i <= n; i++) | ||
308 | checkbig(L, i); | ||
309 | |||
310 | return n; | ||
311 | } else { | ||
312 | bn_push(L); | ||
313 | |||
314 | return 1; | ||
315 | } | ||
316 | } /* bn_new() */ | ||
317 | |||
318 | |||
319 | static int bn_interpose(lua_State *L) { | ||
320 | return interpose(L, BIGNUM_CLASS); | ||
321 | } /* bn_interpose() */ | ||
322 | |||
323 | |||
324 | /* return integral part */ | ||
325 | static inline double intof(double f) { | ||
326 | return (isfinite(f))? floor(fabs(f)) : 0.0; | ||
327 | } /* intof() */ | ||
328 | |||
329 | |||
330 | /* convert integral to BN_ULONG. returns success or failure. */ | ||
331 | static _Bool int2ul(BN_ULONG *ul, double f) { | ||
332 | int exp; | ||
333 | |||
334 | frexp(f, &exp); | ||
335 | |||
336 | if (exp > (int)sizeof *ul * 8) | ||
337 | return 0; | ||
338 | |||
339 | *ul = (BN_ULONG)f; | ||
340 | |||
341 | return 1; | ||
342 | } /* int2ul() */ | ||
343 | |||
344 | |||
345 | /* convert integral BIGNUM. returns success or failure. */ | ||
346 | static _Bool int2bn(BIGNUM **bn, double q) { | ||
347 | unsigned char nib[32], bin[32], *p; | ||
348 | size_t i, n; | ||
349 | double r; | ||
350 | |||
351 | p = nib; | ||
352 | |||
353 | while (q >= 1.0 && p < endof(nib)) { | ||
354 | r = fmod(q, 256.0); | ||
355 | *p++ = r; | ||
356 | q = round((q - r) / 256.0); | ||
357 | } | ||
358 | |||
359 | n = p - nib; | ||
360 | |||
361 | for (i = 0; i < n; i++) { | ||
362 | bin[i] = *--p; | ||
363 | } | ||
364 | |||
365 | if (!(*bn = BN_bin2bn(bin, n, *bn))) | ||
366 | return 0; | ||
367 | |||
368 | return 1; | ||
369 | } /* int2bn() */ | ||
370 | |||
371 | |||
372 | /* convert double to BIGNUM. returns success or failure. */ | ||
373 | static _Bool f2bn(BIGNUM **bn, double f) { | ||
374 | double i = intof(f); | ||
375 | BN_ULONG lu; | ||
376 | |||
377 | if (int2ul(&lu, i)) { | ||
378 | if (!*bn && !(*bn = BN_new())) | ||
379 | return 0; | ||
380 | |||
381 | if (!BN_set_word(*bn, lu)) | ||
382 | return 0; | ||
383 | } else if (!int2bn(bn, i)) | ||
384 | return 0; | ||
385 | |||
386 | BN_set_negative(*bn, signbit(f)); | ||
387 | |||
388 | return 1; | ||
389 | } /* f2bn() */ | ||
390 | |||
391 | |||
392 | static BIGNUM *(checkbig)(lua_State *L, int index, _Bool *lvalue) { | ||
393 | BIGNUM **bn; | ||
394 | const char *dec; | ||
395 | size_t len; | ||
396 | |||
397 | index = lua_absindex(L, index); | ||
398 | |||
399 | switch (lua_type(L, index)) { | ||
400 | case LUA_TSTRING: | ||
401 | *lvalue = 0; | ||
402 | |||
403 | dec = lua_tolstring(L, index, &len); | ||
404 | |||
405 | luaL_argcheck(L, len > 0 && *dec, index, "invalid big number string"); | ||
406 | |||
407 | bn = prepsimple(L, BIGNUM_CLASS); | ||
408 | |||
409 | if (!BN_dec2bn(bn, dec)) | ||
410 | throwssl(L, "bignum"); | ||
411 | |||
412 | lua_replace(L, index); | ||
413 | |||
414 | return *bn; | ||
415 | case LUA_TNUMBER: | ||
416 | *lvalue = 0; | ||
417 | |||
418 | bn = prepsimple(L, BIGNUM_CLASS); | ||
419 | |||
420 | if (!f2bn(bn, lua_tonumber(L, index))) | ||
421 | throwssl(L, "bignum"); | ||
422 | |||
423 | lua_replace(L, index); | ||
424 | |||
425 | return *bn; | ||
426 | default: | ||
427 | *lvalue = 1; | ||
428 | |||
429 | return checksimple(L, index, BIGNUM_CLASS); | ||
430 | } /* switch() */ | ||
431 | } /* checkbig() */ | ||
432 | |||
433 | |||
434 | static void bn_prepops(lua_State *L, BIGNUM **r, BIGNUM **a, BIGNUM **b, _Bool commute) { | ||
435 | _Bool lvalue = 1; | ||
436 | |||
437 | lua_settop(L, 2); /* a, b */ | ||
438 | |||
439 | *a = checkbig(L, 1, &lvalue); | ||
440 | |||
441 | if (!lvalue && commute) | ||
442 | lua_pushvalue(L, 1); | ||
443 | |||
444 | *b = checkbig(L, 2, &lvalue); | ||
445 | |||
446 | if (!lvalue && commute && lua_gettop(L) < 3) | ||
447 | lua_pushvalue(L, 2); | ||
448 | |||
449 | if (lua_gettop(L) < 3) | ||
450 | bn_push(L); | ||
451 | |||
452 | *r = *(BIGNUM **)lua_touserdata(L, 3); | ||
453 | } /* bn_prepops() */ | ||
454 | |||
455 | |||
456 | static int ctx__gc(lua_State *L) { | ||
457 | BN_CTX **ctx = lua_touserdata(L, 1); | ||
458 | |||
459 | BN_CTX_free(*ctx); | ||
460 | *ctx = NULL; | ||
461 | |||
462 | return 0; | ||
463 | } /* ctx__gc() */ | ||
464 | |||
465 | static BN_CTX *getctx(lua_State *L) { | ||
466 | BN_CTX **ctx; | ||
467 | |||
468 | lua_pushcfunction(L, &ctx__gc); | ||
469 | lua_gettable(L, LUA_REGISTRYINDEX); | ||
470 | |||
471 | if (lua_isnil(L, -1)) { | ||
472 | lua_pop(L, 1); | ||
473 | |||
474 | ctx = prepsimple(L, NULL, &ctx__gc); | ||
475 | |||
476 | if (!(*ctx = BN_CTX_new())) | ||
477 | throwssl(L, "bignum"); | ||
478 | |||
479 | lua_pushcfunction(L, &ctx__gc); | ||
480 | lua_pushvalue(L, -2); | ||
481 | lua_settable(L, LUA_REGISTRYINDEX); | ||
482 | } | ||
483 | |||
484 | ctx = lua_touserdata(L, -1); | ||
485 | lua_pop(L, 1); | ||
486 | |||
487 | return *ctx; | ||
488 | } /* getctx() */ | ||
489 | |||
490 | |||
491 | static int bn__add(lua_State *L) { | ||
492 | BIGNUM *r, *a, *b; | ||
493 | |||
494 | bn_prepops(L, &r, &a, &b, 1); | ||
495 | |||
496 | if (!BN_add(r, a, b)) | ||
497 | return throwssl(L, "bignum:__add"); | ||
498 | |||
499 | return 1; | ||
500 | } /* bn__add() */ | ||
501 | |||
502 | |||
503 | static int bn__sub(lua_State *L) { | ||
504 | BIGNUM *r, *a, *b; | ||
505 | |||
506 | bn_prepops(L, &r, &a, &b, 0); | ||
507 | |||
508 | if (!BN_sub(r, a, b)) | ||
509 | return throwssl(L, "bignum:__sub"); | ||
510 | |||
511 | return 1; | ||
512 | } /* bn__sub() */ | ||
513 | |||
514 | |||
515 | static int bn__mul(lua_State *L) { | ||
516 | BIGNUM *r, *a, *b; | ||
517 | |||
518 | bn_prepops(L, &r, &a, &b, 1); | ||
519 | |||
520 | if (!BN_mul(r, a, b, getctx(L))) | ||
521 | return throwssl(L, "bignum:__mul"); | ||
522 | |||
523 | return 1; | ||
524 | } /* bn__mul() */ | ||
525 | |||
526 | |||
527 | static int bn__div(lua_State *L) { | ||
528 | BIGNUM *r, *a, *b; | ||
529 | BN_CTX *ctx; | ||
530 | |||
531 | bn_prepops(L, &r, &a, &b, 0); | ||
532 | |||
533 | if (!BN_div(r, NULL, a, b, getctx(L))) | ||
534 | return throwssl(L, "bignum:__div"); | ||
535 | |||
536 | return 1; | ||
537 | } /* bn__div() */ | ||
538 | |||
539 | |||
540 | static int bn__mod(lua_State *L) { | ||
541 | BIGNUM *r, *a, *b; | ||
542 | BN_CTX *ctx; | ||
543 | |||
544 | bn_prepops(L, &r, &a, &b, 0); | ||
545 | |||
546 | if (!BN_mod(r, a, b, getctx(L))) | ||
547 | return throwssl(L, "bignum:__mod"); | ||
548 | |||
549 | return 1; | ||
550 | } /* bn__mod() */ | ||
551 | |||
552 | |||
553 | static int bn__pow(lua_State *L) { | ||
554 | BIGNUM *r, *a, *b; | ||
555 | BN_CTX *ctx; | ||
556 | |||
557 | bn_prepops(L, &r, &a, &b, 0); | ||
558 | |||
559 | if (!BN_exp(r, a, b, getctx(L))) | ||
560 | return throwssl(L, "bignum:__pow"); | ||
561 | |||
562 | return 1; | ||
563 | } /* bn__pow() */ | ||
564 | |||
565 | |||
566 | static int bn__unm(lua_State *L) { | ||
567 | BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS); | ||
568 | |||
569 | BN_set_negative(a, !BN_is_negative(a)); | ||
570 | |||
571 | return 1; | ||
572 | } /* bn__unm() */ | ||
573 | |||
574 | |||
575 | static int bn__eq(lua_State *L) { | ||
576 | BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS); | ||
577 | BIGNUM *b = checksimple(L, 2, BIGNUM_CLASS); | ||
578 | |||
579 | lua_pushboolean(L, 0 == BN_cmp(a, b)); | ||
580 | |||
581 | return 1; | ||
582 | } /* bn__eq() */ | ||
583 | |||
584 | |||
585 | static int bn__lt(lua_State *L) { | ||
586 | BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS); | ||
587 | BIGNUM *b = checksimple(L, 2, BIGNUM_CLASS); | ||
588 | int cmp = BN_cmp(a, b); | ||
589 | |||
590 | lua_pushboolean(L, cmp == -1); | ||
591 | |||
592 | return 1; | ||
593 | } /* bn__lt() */ | ||
594 | |||
595 | |||
596 | static int bn__le(lua_State *L) { | ||
597 | BIGNUM *a = checksimple(L, 1, BIGNUM_CLASS); | ||
598 | BIGNUM *b = checksimple(L, 2, BIGNUM_CLASS); | ||
599 | int cmp = BN_cmp(a, b); | ||
600 | |||
601 | lua_pushboolean(L, cmp <= 0); | ||
602 | |||
603 | return 1; | ||
604 | } /* bn__le() */ | ||
605 | |||
606 | |||
607 | static int bn__gc(lua_State *L) { | ||
608 | BIGNUM **ud = luaL_checkudata(L, 1, BIGNUM_CLASS); | ||
609 | |||
610 | BN_free(*ud); | ||
611 | *ud = NULL; | ||
612 | |||
613 | return 0; | ||
614 | } /* bn__gc() */ | ||
615 | |||
616 | |||
617 | static int bn__tostring(lua_State *L) { | ||
618 | BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS); | ||
619 | char *txt; | ||
620 | |||
621 | if (!(txt = BN_bn2dec(bn))) | ||
622 | throwssl(L, "bignum:__tostring"); | ||
623 | |||
624 | lua_pushstring(L, txt); | ||
625 | |||
626 | return 1; | ||
627 | } /* bn__tostring() */ | ||
628 | |||
629 | |||
630 | static const luaL_Reg bn_methods[] = { | ||
631 | { NULL, NULL }, | ||
632 | }; | ||
633 | |||
634 | static const luaL_Reg bn_metatable[] = { | ||
635 | { "__add", &bn__add }, | ||
636 | { "__sub", &bn__sub }, | ||
637 | { "__mul", &bn__mul }, | ||
638 | { "__div", &bn__div }, | ||
639 | { "__mod", &bn__mod }, | ||
640 | { "__pow", &bn__pow }, | ||
641 | { "__unm", &bn__unm }, | ||
642 | { "__eq", &bn__eq }, | ||
643 | { "__lt", &bn__lt }, | ||
644 | { "__le", &bn__le }, | ||
645 | { "__gc", &bn__gc }, | ||
646 | { "__tostring", &bn__tostring }, | ||
647 | { NULL, NULL }, | ||
648 | }; | ||
649 | |||
650 | |||
651 | static const luaL_Reg bn_globals[] = { | ||
652 | { "new", &bn_new }, | ||
653 | { "interpose", &bn_interpose }, | ||
654 | { NULL, NULL }, | ||
655 | }; | ||
656 | |||
657 | int luaopen__openssl_bignum(lua_State *L) { | ||
658 | initall(L); | ||
659 | |||
660 | luaL_newlib(L, bn_globals); | ||
661 | |||
662 | return 1; | ||
663 | } /* luaopen__openssl_bignum() */ | ||
664 | |||
665 | |||
666 | /* | ||
667 | * EVP_PKEY - openssl.pubkey | ||
668 | * | ||
669 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
670 | |||
671 | static int bio__gc(lua_State *L) { | ||
672 | BIO **bio = lua_touserdata(L, 1); | ||
673 | |||
674 | BIO_free(*bio); | ||
675 | *bio = NULL; | ||
676 | |||
677 | return 0; | ||
678 | } /* bio__gc() */ | ||
679 | |||
680 | static BIO *getbio(lua_State *L) { | ||
681 | BIO **bio; | ||
682 | |||
683 | lua_pushcfunction(L, &bio__gc); | ||
684 | lua_gettable(L, LUA_REGISTRYINDEX); | ||
685 | |||
686 | if (lua_isnil(L, -1)) { | ||
687 | lua_pop(L, 1); | ||
688 | |||
689 | bio = prepsimple(L, NULL, &bio__gc); | ||
690 | |||
691 | if (!(*bio = BIO_new(BIO_s_mem()))) | ||
692 | throwssl(L, "BIO_new"); | ||
693 | |||
694 | lua_pushcfunction(L, &bio__gc); | ||
695 | lua_pushvalue(L, -2); | ||
696 | lua_settable(L, LUA_REGISTRYINDEX); | ||
697 | } | ||
698 | |||
699 | bio = lua_touserdata(L, -1); | ||
700 | lua_pop(L, 1); | ||
701 | |||
702 | BIO_reset(*bio); | ||
703 | |||
704 | return *bio; | ||
705 | } /* getbio() */ | ||
706 | |||
707 | |||
708 | static int pk_new(lua_State *L) { | ||
709 | EVP_PKEY **ud; | ||
710 | |||
711 | lua_settop(L, 1); | ||
712 | |||
713 | ud = prepsimple(L, PUBKEY_CLASS); | ||
714 | |||
715 | if (lua_istable(L, 1)) { | ||
716 | int type = EVP_PKEY_RSA; | ||
717 | unsigned bits = 1024; | ||
718 | unsigned exp = 65537; | ||
719 | int curve = NID_X9_62_prime192v1; | ||
720 | const char *id; | ||
721 | lua_Number n; | ||
722 | |||
723 | if (!lua_istable(L, 1)) | ||
724 | goto creat; | ||
725 | |||
726 | if (loadfield(L, 1, "type", LUA_TSTRING, &id)) { | ||
727 | static const struct { int nid; const char *sn; } types[] = { | ||
728 | { EVP_PKEY_RSA, "RSA" }, | ||
729 | { EVP_PKEY_DSA, "DSA" }, | ||
730 | { EVP_PKEY_DH, "DH" }, | ||
731 | { EVP_PKEY_EC, "EC" }, | ||
732 | }; | ||
733 | unsigned i; | ||
734 | |||
735 | type = OBJ_sn2nid(id); | ||
736 | |||
737 | if (NID_undef == (type = EVP_PKEY_type(OBJ_sn2nid(id)))) { | ||
738 | for (i = 0; i < countof(types); i++) { | ||
739 | if (strieq(id, types[i].sn)) { | ||
740 | type = types[i].nid; | ||
741 | break; | ||
742 | } | ||
743 | } | ||
744 | } | ||
745 | |||
746 | luaL_argcheck(L, type != NID_undef, 1, lua_pushfstring(L, "%s: invalid key type", id)); | ||
747 | } | ||
748 | |||
749 | if (loadfield(L, 1, "bits", LUA_TNUMBER, &n)) { | ||
750 | luaL_argcheck(L, n > 0 && n < UINT_MAX, 1, lua_pushfstring(L, "%f: `bits' invalid", n)); | ||
751 | bits = (unsigned)n; | ||
752 | } | ||
753 | |||
754 | if (loadfield(L, 1, "exp", LUA_TNUMBER, &n)) { | ||
755 | luaL_argcheck(L, n > 0 && n < UINT_MAX, 1, lua_pushfstring(L, "%f: `exp' invalid", n)); | ||
756 | exp = (unsigned)n; | ||
757 | } | ||
758 | |||
759 | if (loadfield(L, 1, "curve", LUA_TSTRING, &id)) { | ||
760 | curve = OBJ_sn2nid(id); | ||
761 | luaL_argcheck(L, curve != NID_undef, 1, lua_pushfstring(L, "%s: invalid curve", id)); | ||
762 | } | ||
763 | |||
764 | creat: | ||
765 | if (!(*ud = EVP_PKEY_new())) | ||
766 | return throwssl(L, "pubkey.new"); | ||
767 | |||
768 | switch (EVP_PKEY_type(type)) { | ||
769 | case EVP_PKEY_RSA: { | ||
770 | RSA *rsa; | ||
771 | |||
772 | if (!(rsa = RSA_generate_key(bits, exp, 0, 0))) | ||
773 | return throwssl(L, "pubkey.new"); | ||
774 | |||
775 | EVP_PKEY_set1_RSA(*ud, rsa); | ||
776 | |||
777 | RSA_free(rsa); | ||
778 | |||
779 | break; | ||
780 | } | ||
781 | case EVP_PKEY_DSA: { | ||
782 | DSA *dsa; | ||
783 | |||
784 | if (!(dsa = DSA_generate_parameters(bits, 0, 0, 0, 0, 0, 0))) | ||
785 | return throwssl(L, "pubkey.new"); | ||
786 | |||
787 | if (!DSA_generate_key(dsa)) { | ||
788 | DSA_free(dsa); | ||
789 | return throwssl(L, "pubkey.new"); | ||
790 | } | ||
791 | |||
792 | EVP_PKEY_set1_DSA(*ud, dsa); | ||
793 | |||
794 | DSA_free(dsa); | ||
795 | |||
796 | break; | ||
797 | } | ||
798 | case EVP_PKEY_DH: { | ||
799 | DH *dh; | ||
800 | |||
801 | if (!(dh = DH_generate_parameters(bits, exp, 0, 0))) | ||
802 | return throwssl(L, "pubkey.new"); | ||
803 | |||
804 | if (!DH_generate_key(dh)) { | ||
805 | DH_free(dh); | ||
806 | return throwssl(L, "pubkey.new"); | ||
807 | } | ||
808 | |||
809 | EVP_PKEY_set1_DH(*ud, dh); | ||
810 | |||
811 | DH_free(dh); | ||
812 | |||
813 | break; | ||
814 | } | ||
815 | #ifndef OPENSSL_NO_EC | ||
816 | case EVP_PKEY_EC: { | ||
817 | EC_GROUP *grp; | ||
818 | EC_KEY *key; | ||
819 | |||
820 | if (!(grp = EC_GROUP_new_by_curve_name(curve))) | ||
821 | return throwssl(L, "pubkey.new"); | ||
822 | |||
823 | EC_GROUP_set_asn1_flag(grp, OPENSSL_EC_NAMED_CURVE); | ||
824 | |||
825 | /* compressed points patented */ | ||
826 | EC_GROUP_set_point_conversion_form(grp, POINT_CONVERSION_UNCOMPRESSED); | ||
827 | |||
828 | if (!(key = EC_KEY_new())) { | ||
829 | EC_GROUP_free(grp); | ||
830 | return throwssl(L, "pubkey.new"); | ||
831 | } | ||
832 | |||
833 | EC_KEY_set_group(key, grp); | ||
834 | |||
835 | EC_GROUP_free(grp); | ||
836 | |||
837 | if (!EC_KEY_generate_key(key)) { | ||
838 | EC_KEY_free(key); | ||
839 | return throwssl(L, "pubkey.new"); | ||
840 | } | ||
841 | |||
842 | EVP_PKEY_set1_EC_KEY(*ud, key); | ||
843 | |||
844 | EC_KEY_free(key); | ||
845 | |||
846 | break; | ||
847 | } | ||
848 | #endif | ||
849 | default: | ||
850 | return luaL_error(L, "%d: unknown EVP base type (%d)", EVP_PKEY_type(type), type); | ||
851 | } /* switch() */ | ||
852 | } else { | ||
853 | const char *pem; | ||
854 | size_t len; | ||
855 | BIO *bio; | ||
856 | int ok; | ||
857 | |||
858 | if (!(*ud = EVP_PKEY_new())) | ||
859 | return throwssl(L, "pubkey.new"); | ||
860 | |||
861 | switch (lua_type(L, 1)) { | ||
862 | case LUA_TSTRING: | ||
863 | pem = luaL_checklstring(L, 1, &len); | ||
864 | |||
865 | if (!(bio = BIO_new_mem_buf((void *)pem, len))) | ||
866 | return throwssl(L, "pubkey.new"); | ||
867 | |||
868 | if (strstr(pem, "PUBLIC KEY")) { | ||
869 | ok = !!PEM_read_bio_PUBKEY(bio, ud, 0, 0); | ||
870 | } else { | ||
871 | ok = !!PEM_read_bio_PrivateKey(bio, ud, 0, 0); | ||
872 | } | ||
873 | |||
874 | BIO_free(bio); | ||
875 | |||
876 | if (!ok) | ||
877 | return throwssl(L, "pubkey.new"); | ||
878 | |||
879 | break; | ||
880 | default: | ||
881 | return luaL_error(L, "%s: unknown key initializer", lua_typename(L, lua_type(L, 1))); | ||
882 | } /* switch() */ | ||
883 | } | ||
884 | |||
885 | return 1; | ||
886 | } /* pk_new() */ | ||
887 | |||
888 | |||
889 | static int pk_interpose(lua_State *L) { | ||
890 | return interpose(L, X509_NAME_CLASS); | ||
891 | } /* pk_interpose() */ | ||
892 | |||
893 | |||
894 | static int pk_type(lua_State *L) { | ||
895 | EVP_PKEY *key = checksimple(L, 1, PUBKEY_CLASS); | ||
896 | int nid = key->type; | ||
897 | |||
898 | pushnid(L, nid); | ||
899 | |||
900 | return 1; | ||
901 | } /* pk_type() */ | ||
902 | |||
903 | |||
904 | static int pk_setPublicKey(lua_State *L) { | ||
905 | EVP_PKEY **key = luaL_checkudata(L, 1, PUBKEY_CLASS); | ||
906 | const char *pem; | ||
907 | size_t len; | ||
908 | BIO *bio; | ||
909 | int ok; | ||
910 | |||
911 | lua_settop(L, 2); | ||
912 | |||
913 | pem = luaL_checklstring(L, 2, &len); | ||
914 | |||
915 | if (!(bio = BIO_new_mem_buf((void *)pem, len))) | ||
916 | return throwssl(L, "pubkey.new"); | ||
917 | |||
918 | ok = !!PEM_read_bio_PUBKEY(bio, key, 0, 0); | ||
919 | |||
920 | BIO_free(bio); | ||
921 | |||
922 | if (!ok) | ||
923 | return throwssl(L, "pubkey.new"); | ||
924 | |||
925 | lua_pushboolean(L, 1); | ||
926 | |||
927 | return 1; | ||
928 | } /* pk_setPublicKey() */ | ||
929 | |||
930 | |||
931 | static int pk_setPrivateKey(lua_State *L) { | ||
932 | EVP_PKEY **key = luaL_checkudata(L, 1, PUBKEY_CLASS); | ||
933 | const char *pem; | ||
934 | size_t len; | ||
935 | BIO *bio; | ||
936 | int ok; | ||
937 | |||
938 | lua_settop(L, 2); | ||
939 | |||
940 | pem = luaL_checklstring(L, 2, &len); | ||
941 | |||
942 | if (!(bio = BIO_new_mem_buf((void *)pem, len))) | ||
943 | return throwssl(L, "pubkey.new"); | ||
944 | |||
945 | ok = !!PEM_read_bio_PrivateKey(bio, key, 0, 0); | ||
946 | |||
947 | BIO_free(bio); | ||
948 | |||
949 | if (!ok) | ||
950 | return throwssl(L, "pubkey.new"); | ||
951 | |||
952 | lua_pushboolean(L, 1); | ||
953 | |||
954 | return 1; | ||
955 | } /* pk_setPrivateKEY() */ | ||
956 | |||
957 | |||
958 | static int pk_sign(lua_State *L) { | ||
959 | EVP_PKEY *key = checksimple(L, 1, PUBKEY_CLASS); | ||
960 | EVP_MD_CTX *md = luaL_checkudata(L, 2, DIGEST_CLASS); | ||
961 | luaL_Buffer B; | ||
962 | unsigned n; | ||
963 | |||
964 | if (LUAL_BUFFERSIZE < EVP_PKEY_size(key)) | ||
965 | return luaL_error(L, "pubkey:sign: LUAL_BUFFERSIZE(%u) < EVP_PKEY_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)EVP_PKEY_size(key)); | ||
966 | |||
967 | luaL_buffinit(L, &B); | ||
968 | n = LUAL_BUFFERSIZE; | ||
969 | |||
970 | if (!EVP_SignFinal(md, (void *)luaL_prepbuffer(&B), &n, key)) | ||
971 | return throwssl(L, "pubkey:sign"); | ||
972 | |||
973 | luaL_addsize(&B, n); | ||
974 | luaL_pushresult(&B); | ||
975 | |||
976 | return 1; | ||
977 | } /* pk_sign() */ | ||
978 | |||
979 | |||
980 | static int pk_verify(lua_State *L) { | ||
981 | EVP_PKEY *key = checksimple(L, 1, PUBKEY_CLASS); | ||
982 | size_t len; | ||
983 | const void *sig = luaL_checklstring(L, 2, &len); | ||
984 | EVP_MD_CTX *md = luaL_checkudata(L, 3, DIGEST_CLASS); | ||
985 | |||
986 | switch (EVP_VerifyFinal(md, sig, len, key)) { | ||
987 | case 0: /* WRONG */ | ||
988 | ERR_clear_error(); | ||
989 | lua_pushboolean(L, 0); | ||
990 | |||
991 | break; | ||
992 | case 1: /* OK */ | ||
993 | lua_pushboolean(L, 1); | ||
994 | |||
995 | break; | ||
996 | default: | ||
997 | return throwssl(L, "pubkey:verify"); | ||
998 | } | ||
999 | |||
1000 | return 1; | ||
1001 | } /* pk_verify() */ | ||
1002 | |||
1003 | |||
1004 | static int pk_toPEM(lua_State *L) { | ||
1005 | EVP_PKEY *key = checksimple(L, 1, PUBKEY_CLASS); | ||
1006 | int top, i, ok; | ||
1007 | BIO *bio; | ||
1008 | char *pem; | ||
1009 | long len; | ||
1010 | |||
1011 | if (1 == (top = lua_gettop(L))) { | ||
1012 | lua_pushstring(L, "publickey"); | ||
1013 | ++top; | ||
1014 | } | ||
1015 | |||
1016 | bio = getbio(L); | ||
1017 | |||
1018 | for (i = 2; i <= top; i++) { | ||
1019 | static const char *opts[] = { | ||
1020 | "public", "PublicKey", | ||
1021 | "private", "PrivateKey", | ||
1022 | // "params", "Parameters", | ||
1023 | NULL, | ||
1024 | }; | ||
1025 | |||
1026 | switch (checkoption(L, i, NULL, opts)) { | ||
1027 | case 0: case 1: /* public, PublicKey */ | ||
1028 | if (!PEM_write_bio_PUBKEY(bio, key)) | ||
1029 | return throwssl(L, "pubkey:__tostring"); | ||
1030 | |||
1031 | len = BIO_get_mem_data(bio, &pem); | ||
1032 | lua_pushlstring(L, pem, len); | ||
1033 | |||
1034 | BIO_reset(bio); | ||
1035 | break; | ||
1036 | case 2: case 3: /* private, PrivateKey */ | ||
1037 | if (!PEM_write_bio_PrivateKey(bio, key, 0, 0, 0, 0, 0)) | ||
1038 | throwssl(L, "pubkey:__tostring"); | ||
1039 | |||
1040 | len = BIO_get_mem_data(bio, &pem); | ||
1041 | lua_pushlstring(L, pem, len); | ||
1042 | |||
1043 | break; | ||
1044 | #if 0 | ||
1045 | case 4: case 5: /* params, Parameters */ | ||
1046 | /* EVP_PKEY_base_id not in OS X */ | ||
1047 | switch (EVP_PKEY_type(key->type)) { | ||
1048 | case EVP_PKEY_RSA: | ||
1049 | break; | ||
1050 | case EVP_PKEY_DSA: { | ||
1051 | DSA *dsa = EVP_PKEY_get1_DSA(key); | ||
1052 | |||
1053 | ok = !!PEM_write_bio_DSAparams(bio, dsa); | ||
1054 | |||
1055 | DSA_free(dsa); | ||
1056 | |||
1057 | if (!ok) | ||
1058 | return throwssl(L, "pubkey:__tostring"); | ||
1059 | |||
1060 | break; | ||
1061 | } | ||
1062 | case EVP_PKEY_DH: { | ||
1063 | DH *dh = EVP_PKEY_get1_DH(key); | ||
1064 | |||
1065 | ok = !!PEM_write_bio_DHparams(bio, dh); | ||
1066 | |||
1067 | DH_free(dh); | ||
1068 | |||
1069 | if (!ok) | ||
1070 | return throwssl(L, "pubkey:__tostring"); | ||
1071 | |||
1072 | break; | ||
1073 | } | ||
1074 | #ifndef OPENSSL_NO_EC | ||
1075 | case EVP_PKEY_EC: { | ||
1076 | EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); | ||
1077 | const EC_GROUP *grp = EC_KEY_get0_group(ec); | ||
1078 | |||
1079 | ok = !!PEM_write_bio_ECPKParameters(bio, grp); | ||
1080 | |||
1081 | EC_KEY_free(ec); | ||
1082 | |||
1083 | if (!ok) | ||
1084 | return throwssl(L, "pubkey:__tostring"); | ||
1085 | |||
1086 | break; | ||
1087 | } | ||
1088 | #endif | ||
1089 | default: | ||
1090 | return luaL_error(L, "%d: unknown EVP base type", EVP_PKEY_type(key->type)); | ||
1091 | } | ||
1092 | |||
1093 | lua_pushlstring(L, pem, len); | ||
1094 | |||
1095 | BIO_reset(bio); | ||
1096 | |||
1097 | break; | ||
1098 | #endif | ||
1099 | default: | ||
1100 | lua_pushnil(L); | ||
1101 | |||
1102 | break; | ||
1103 | } /* switch() */ | ||
1104 | } /* for() */ | ||
1105 | |||
1106 | return lua_gettop(L) - top; | ||
1107 | } /* pk_toPEM() */ | ||
1108 | |||
1109 | |||
1110 | static int pk__tostring(lua_State *L) { | ||
1111 | EVP_PKEY *key = checksimple(L, 1, PUBKEY_CLASS); | ||
1112 | BIO *bio = getbio(L); | ||
1113 | char *pem; | ||
1114 | long len; | ||
1115 | int ok; | ||
1116 | |||
1117 | if (!PEM_write_bio_PUBKEY(bio, key)) | ||
1118 | return throwssl(L, "pubkey:__tostring"); | ||
1119 | |||
1120 | len = BIO_get_mem_data(bio, &pem); | ||
1121 | lua_pushlstring(L, pem, len); | ||
1122 | |||
1123 | return 1; | ||
1124 | } /* pk__tostring() */ | ||
1125 | |||
1126 | |||
1127 | static int pk__gc(lua_State *L) { | ||
1128 | EVP_PKEY **ud = luaL_checkudata(L, 1, PUBKEY_CLASS); | ||
1129 | |||
1130 | EVP_PKEY_free(*ud); | ||
1131 | *ud = NULL; | ||
1132 | |||
1133 | return 0; | ||
1134 | } /* pk__gc() */ | ||
1135 | |||
1136 | |||
1137 | static const luaL_Reg pk_methods[] = { | ||
1138 | { "type", &pk_type }, | ||
1139 | { "setPublicKey", &pk_setPublicKey }, | ||
1140 | { "setPrivateKey", &pk_setPrivateKey }, | ||
1141 | { "sign", &pk_sign }, | ||
1142 | { "verify", &pk_verify }, | ||
1143 | { "toPEM", &pk_toPEM }, | ||
1144 | { NULL, NULL }, | ||
1145 | }; | ||
1146 | |||
1147 | static const luaL_Reg pk_metatable[] = { | ||
1148 | { "__tostring", &pk__tostring }, | ||
1149 | { "__gc", &pk__gc }, | ||
1150 | { NULL, NULL }, | ||
1151 | }; | ||
1152 | |||
1153 | |||
1154 | static const luaL_Reg pk_globals[] = { | ||
1155 | { "new", &pk_new }, | ||
1156 | { "interpose", &pk_interpose }, | ||
1157 | { NULL, NULL }, | ||
1158 | }; | ||
1159 | |||
1160 | int luaopen__openssl_pubkey(lua_State *L) { | ||
1161 | initall(L); | ||
1162 | |||
1163 | luaL_newlib(L, pk_globals); | ||
1164 | |||
1165 | return 1; | ||
1166 | } /* luaopen__openssl_pubkey() */ | ||
1167 | |||
1168 | |||
1169 | /* | ||
1170 | * X509_NAME - openssl.x509.name | ||
1171 | * | ||
1172 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
1173 | |||
1174 | static X509_NAME *xn_dup(lua_State *L, X509_NAME *name) { | ||
1175 | X509_NAME **ud = prepsimple(L, X509_NAME_CLASS); | ||
1176 | |||
1177 | if (!(*ud = X509_NAME_dup(name))) | ||
1178 | throwssl(L, "x509.name.dup"); | ||
1179 | |||
1180 | return *ud; | ||
1181 | } /* xn_dup() */ | ||
1182 | |||
1183 | |||
1184 | static int xn_new(lua_State *L) { | ||
1185 | X509_NAME **ud = prepsimple(L, X509_NAME_CLASS); | ||
1186 | |||
1187 | if (!(*ud = X509_NAME_new())) | ||
1188 | return throwssl(L, "x509.name.new"); | ||
1189 | |||
1190 | return 1; | ||
1191 | } /* xn_new() */ | ||
1192 | |||
1193 | |||
1194 | static int xn_interpose(lua_State *L) { | ||
1195 | return interpose(L, X509_NAME_CLASS); | ||
1196 | } /* xn_interpose() */ | ||
1197 | |||
1198 | |||
1199 | static int xn_add(lua_State *L) { | ||
1200 | X509_NAME *name = checksimple(L, 1, X509_NAME_CLASS); | ||
1201 | const char *nid = luaL_checkstring(L, 2); | ||
1202 | size_t len; | ||
1203 | const char *txt = luaL_checklstring(L, 3, &len); | ||
1204 | ASN1_OBJECT *obj; | ||
1205 | int ok; | ||
1206 | |||
1207 | if (!(obj = OBJ_txt2obj(nid, 0))) | ||
1208 | return luaL_error(L, "x509.name:add: %s: invalid NID", nid); | ||
1209 | |||
1210 | ok = !!X509_NAME_add_entry_by_OBJ(name, obj, MBSTRING_ASC, (unsigned char *)txt, len, -1, 0); | ||
1211 | |||
1212 | ASN1_OBJECT_free(obj); | ||
1213 | |||
1214 | if (!ok) | ||
1215 | return throwssl(L, "x509.name:add"); | ||
1216 | |||
1217 | lua_pushboolean(L, 1); | ||
1218 | |||
1219 | return 1; | ||
1220 | } /* xn_add() */ | ||
1221 | |||
1222 | |||
1223 | static int xn_all(lua_State *L) { | ||
1224 | X509_NAME *name = checksimple(L, 1, X509_NAME_CLASS); | ||
1225 | int count = X509_NAME_entry_count(name); | ||
1226 | X509_NAME_ENTRY *entry; | ||
1227 | ASN1_OBJECT *obj; | ||
1228 | const char *id; | ||
1229 | char txt[256]; | ||
1230 | int i, nid, len; | ||
1231 | |||
1232 | lua_newtable(L); | ||
1233 | |||
1234 | for (i = 0; i < count; i++) { | ||
1235 | if (!(entry = X509_NAME_get_entry(name, i))) | ||
1236 | continue; | ||
1237 | |||
1238 | lua_newtable(L); | ||
1239 | |||
1240 | obj = X509_NAME_ENTRY_get_object(entry); | ||
1241 | nid = OBJ_obj2nid(obj); | ||
1242 | |||
1243 | if (0 > (len = OBJ_obj2txt(txt, sizeof txt, obj, 1))) | ||
1244 | return throwssl(L, "x509.name:all"); | ||
1245 | |||
1246 | lua_pushlstring(L, txt, len); | ||
1247 | |||
1248 | if (nid != NID_undef && ((id = OBJ_nid2ln(nid)) || (id = OBJ_nid2sn(nid)))) | ||
1249 | lua_pushstring(L, id); | ||
1250 | else | ||
1251 | lua_pushvalue(L, -1); | ||
1252 | |||
1253 | if (nid != NID_undef && (id = OBJ_nid2sn(nid))) | ||
1254 | lua_pushstring(L, id); | ||
1255 | else | ||
1256 | lua_pushvalue(L, -1); | ||
1257 | |||
1258 | lua_setfield(L, -4, "sn"); | ||
1259 | lua_setfield(L, -3, "ln"); | ||
1260 | lua_setfield(L, -2, "id"); | ||
1261 | |||
1262 | len = ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry)); | ||
1263 | lua_pushlstring(L, (char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), len); | ||
1264 | |||
1265 | lua_setfield(L, -2, "blob"); | ||
1266 | |||
1267 | lua_rawseti(L, -2, i + 1); | ||
1268 | } | ||
1269 | |||
1270 | return 1; | ||
1271 | } /* xn_all() */ | ||
1272 | |||
1273 | |||
1274 | static int xn__next(lua_State *L) { | ||
1275 | X509_NAME *name = checksimple(L, lua_upvalueindex(1), X509_NAME_CLASS); | ||
1276 | X509_NAME_ENTRY *entry; | ||
1277 | ASN1_OBJECT *obj; | ||
1278 | const char *id; | ||
1279 | char txt[256]; | ||
1280 | int i, n, nid, len; | ||
1281 | |||
1282 | lua_settop(L, 0); | ||
1283 | |||
1284 | i = lua_tointeger(L, lua_upvalueindex(2)); | ||
1285 | n = X509_NAME_entry_count(name); | ||
1286 | |||
1287 | while (i < n) { | ||
1288 | if (!(entry = X509_NAME_get_entry(name, i++))) | ||
1289 | continue; | ||
1290 | |||
1291 | obj = X509_NAME_ENTRY_get_object(entry); | ||
1292 | nid = OBJ_obj2nid(obj); | ||
1293 | |||
1294 | if (nid != NID_undef && ((id = OBJ_nid2sn(nid)) || (id = OBJ_nid2ln(nid)))) { | ||
1295 | lua_pushstring(L, id); | ||
1296 | } else { | ||
1297 | if (0 > (len = OBJ_obj2txt(txt, sizeof txt, obj, 1))) | ||
1298 | return throwssl(L, "x509.name:__pairs"); | ||
1299 | |||
1300 | lua_pushlstring(L, txt, len); | ||
1301 | } | ||
1302 | |||
1303 | len = ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry)); | ||
1304 | lua_pushlstring(L, (char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), len); | ||
1305 | |||
1306 | break; | ||
1307 | } | ||
1308 | |||
1309 | lua_pushinteger(L, i); | ||
1310 | lua_replace(L, lua_upvalueindex(2)); | ||
1311 | |||
1312 | return lua_gettop(L); | ||
1313 | } /* xn__next() */ | ||
1314 | |||
1315 | static int xn__pairs(lua_State *L) { | ||
1316 | lua_settop(L, 1); | ||
1317 | lua_pushinteger(L, 0); | ||
1318 | |||
1319 | lua_pushcclosure(L, &xn__next, 2); | ||
1320 | |||
1321 | return 1; | ||
1322 | } /* xn__pairs() */ | ||
1323 | |||
1324 | |||
1325 | static int xn__gc(lua_State *L) { | ||
1326 | X509_NAME **ud = luaL_checkudata(L, 1, X509_NAME_CLASS); | ||
1327 | |||
1328 | X509_NAME_free(*ud); | ||
1329 | *ud = NULL; | ||
1330 | |||
1331 | return 0; | ||
1332 | } /* xn__gc() */ | ||
1333 | |||
1334 | |||
1335 | static int xn__tostring(lua_State *L) { | ||
1336 | X509_NAME *name = checksimple(L, 1, X509_NAME_CLASS); | ||
1337 | char txt[1024] = { 0 }; | ||
1338 | |||
1339 | /* FIXME: oneline is deprecated */ | ||
1340 | X509_NAME_oneline(name, txt, sizeof txt); | ||
1341 | |||
1342 | lua_pushstring(L, txt); | ||
1343 | |||
1344 | return 1; | ||
1345 | } /* xn__tostring() */ | ||
1346 | |||
1347 | |||
1348 | static const luaL_Reg xn_methods[] = { | ||
1349 | { "add", &xn_add }, | ||
1350 | { "all", &xn_all }, | ||
1351 | { NULL, NULL }, | ||
1352 | }; | ||
1353 | |||
1354 | static const luaL_Reg xn_metatable[] = { | ||
1355 | { "__pairs", &xn__pairs }, | ||
1356 | { "__gc", &xn__gc }, | ||
1357 | { "__tostring", &xn__tostring }, | ||
1358 | { NULL, NULL }, | ||
1359 | }; | ||
1360 | |||
1361 | |||
1362 | static const luaL_Reg xn_globals[] = { | ||
1363 | { "new", &xn_new }, | ||
1364 | { "interpose", &xn_interpose }, | ||
1365 | { NULL, NULL }, | ||
1366 | }; | ||
1367 | |||
1368 | int luaopen__openssl_x509_name(lua_State *L) { | ||
1369 | initall(L); | ||
1370 | |||
1371 | luaL_newlib(L, xn_globals); | ||
1372 | |||
1373 | return 1; | ||
1374 | } /* luaopen__openssl_x509_name() */ | ||
1375 | |||
1376 | |||
1377 | /* | ||
1378 | * GENERAL_NAMES - openssl.x509.altname | ||
1379 | * | ||
1380 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
1381 | |||
1382 | static GENERAL_NAMES *gn_dup(lua_State *L, GENERAL_NAMES *gens) { | ||
1383 | GENERAL_NAMES **ud = prepsimple(L, X509_GENS_CLASS); | ||
1384 | |||
1385 | if (!(*ud = sk_GENERAL_NAME_dup(gens))) | ||
1386 | throwssl(L, "x509.altname.dup"); | ||
1387 | |||
1388 | return *ud; | ||
1389 | } /* gn_dup() */ | ||
1390 | |||
1391 | |||
1392 | static int gn_new(lua_State *L) { | ||
1393 | GENERAL_NAMES **ud = prepsimple(L, X509_GENS_CLASS); | ||
1394 | |||
1395 | if (!(*ud = sk_GENERAL_NAME_new_null())) | ||
1396 | return throwssl(L, "x509.altname.new"); | ||
1397 | |||
1398 | return 1; | ||
1399 | } /* gn_new() */ | ||
1400 | |||
1401 | |||
1402 | static int gn_interpose(lua_State *L) { | ||
1403 | return interpose(L, X509_GENS_CLASS); | ||
1404 | } /* gn_interpose() */ | ||
1405 | |||
1406 | |||
1407 | static int gn_setCritical(lua_State *L) { | ||
1408 | GENERAL_NAMES *gens = checksimple(L, 1, X509_GENS_CLASS); | ||
1409 | |||
1410 | return 0; | ||
1411 | } /* gn_setCritical() */ | ||
1412 | |||
1413 | |||
1414 | static int gn_checktype(lua_State *L, int index) { | ||
1415 | static const struct { int type; const char *name; } table[] = { | ||
1416 | { GEN_EMAIL, "RFC822Name" }, | ||
1417 | { GEN_EMAIL, "RFC822" }, | ||
1418 | { GEN_EMAIL, "email" }, | ||
1419 | { GEN_URI, "UniformResourceIdentifier" }, | ||
1420 | { GEN_URI, "URI" }, | ||
1421 | { GEN_DNS, "DNSName" }, | ||
1422 | { GEN_DNS, "DNS" }, | ||
1423 | { GEN_IPADD, "IPAddress" }, | ||
1424 | { GEN_IPADD, "IP" }, | ||
1425 | }; | ||
1426 | const char *type = luaL_checkstring(L, index); | ||
1427 | unsigned i; | ||
1428 | |||
1429 | for (i = 0; i < countof(table); i++) { | ||
1430 | if (strieq(table[i].name, type)) | ||
1431 | return table[i].type; | ||
1432 | } | ||
1433 | |||
1434 | return luaL_error(L, "%s: invalid type", type), 0; | ||
1435 | } /* gn_checktype() */ | ||
1436 | |||
1437 | |||
1438 | static int gn_add(lua_State *L) { | ||
1439 | GENERAL_NAMES *gens = checksimple(L, 1, X509_GENS_CLASS); | ||
1440 | int type = gn_checktype(L, 2); | ||
1441 | size_t len; | ||
1442 | const char *txt = luaL_checklstring(L, 3, &len); | ||
1443 | GENERAL_NAME *gen = NULL; | ||
1444 | union { struct in6_addr in6; struct in_addr in; } ip; | ||
1445 | |||
1446 | if (type == GEN_IPADD) { | ||
1447 | if (strchr(txt, ':')) { | ||
1448 | if (1 != inet_pton(AF_INET6, txt, &ip.in6)) | ||
1449 | return luaL_error(L, "%s: invalid address", txt); | ||
1450 | |||
1451 | txt = (char *)ip.in6.s6_addr; | ||
1452 | len = 16; | ||
1453 | } else { | ||
1454 | if (1 != inet_pton(AF_INET, txt, &ip.in)) | ||
1455 | return luaL_error(L, "%s: invalid address", txt); | ||
1456 | |||
1457 | txt = (char *)&ip.in.s_addr; | ||
1458 | len = 4; | ||
1459 | } | ||
1460 | } | ||
1461 | |||
1462 | if (!(gen = GENERAL_NAME_new())) | ||
1463 | goto error; | ||
1464 | |||
1465 | gen->type = type; | ||
1466 | |||
1467 | if (!(gen->d.ia5 = M_ASN1_IA5STRING_new())) | ||
1468 | goto error; | ||
1469 | |||
1470 | if (!ASN1_STRING_set(gen->d.ia5, (unsigned char *)txt, len)) | ||
1471 | goto error; | ||
1472 | |||
1473 | sk_GENERAL_NAME_push(gens, gen); | ||
1474 | |||
1475 | lua_pushboolean(L, 1); | ||
1476 | |||
1477 | return 1; | ||
1478 | error: | ||
1479 | GENERAL_NAME_free(gen); | ||
1480 | |||
1481 | return throwssl(L, "x509.altname:add"); | ||
1482 | } /* gn_add() */ | ||
1483 | |||
1484 | |||
1485 | static int gn__next(lua_State *L) { | ||
1486 | GENERAL_NAMES *gens = checksimple(L, lua_upvalueindex(1), X509_GENS_CLASS); | ||
1487 | int i = lua_tointeger(L, lua_upvalueindex(2)); | ||
1488 | int n = sk_GENERAL_NAME_num(gens); | ||
1489 | |||
1490 | lua_settop(L, 0); | ||
1491 | |||
1492 | while (i < n) { | ||
1493 | GENERAL_NAME *name; | ||
1494 | const char *tag, *txt; | ||
1495 | size_t len; | ||
1496 | union { struct in_addr in; struct in6_addr in6; } ip; | ||
1497 | char buf[INET6_ADDRSTRLEN + 1]; | ||
1498 | int af; | ||
1499 | |||
1500 | if (!(name = sk_GENERAL_NAME_value(gens, i++))) | ||
1501 | continue; | ||
1502 | |||
1503 | switch (name->type) { | ||
1504 | case GEN_EMAIL: | ||
1505 | tag = "email"; | ||
1506 | txt = (char *)M_ASN1_STRING_data(name->d.rfc822Name); | ||
1507 | len = M_ASN1_STRING_length(name->d.rfc822Name); | ||
1508 | |||
1509 | break; | ||
1510 | case GEN_URI: | ||
1511 | tag = "URI"; | ||
1512 | txt = (char *)M_ASN1_STRING_data(name->d.uniformResourceIdentifier); | ||
1513 | len = M_ASN1_STRING_length(name->d.uniformResourceIdentifier); | ||
1514 | |||
1515 | break; | ||
1516 | case GEN_DNS: | ||
1517 | tag = "DNS"; | ||
1518 | txt = (char *)M_ASN1_STRING_data(name->d.dNSName); | ||
1519 | len = M_ASN1_STRING_length(name->d.dNSName); | ||
1520 | |||
1521 | break; | ||
1522 | case GEN_IPADD: | ||
1523 | tag = "IP"; | ||
1524 | txt = (char *)M_ASN1_STRING_data(name->d.iPAddress); | ||
1525 | len = M_ASN1_STRING_length(name->d.iPAddress); | ||
1526 | |||
1527 | switch (len) { | ||
1528 | case 16: | ||
1529 | memcpy(ip.in6.s6_addr, txt, 16); | ||
1530 | af = AF_INET6; | ||
1531 | |||
1532 | break; | ||
1533 | case 4: | ||
1534 | memcpy(&ip.in.s_addr, txt, 4); | ||
1535 | af = AF_INET; | ||
1536 | |||
1537 | break; | ||
1538 | default: | ||
1539 | continue; | ||
1540 | } | ||
1541 | |||
1542 | if (!(txt = inet_ntop(af, &ip, buf, sizeof buf))) | ||
1543 | continue; | ||
1544 | |||
1545 | len = strlen(txt); | ||
1546 | |||
1547 | break; | ||
1548 | default: | ||
1549 | continue; | ||
1550 | } | ||
1551 | |||
1552 | lua_pushstring(L, tag); | ||
1553 | lua_pushlstring(L, txt, len); | ||
1554 | |||
1555 | break; | ||
1556 | } | ||
1557 | |||
1558 | lua_pushinteger(L, i); | ||
1559 | lua_replace(L, lua_upvalueindex(2)); | ||
1560 | |||
1561 | return lua_gettop(L); | ||
1562 | } /* gn__next() */ | ||
1563 | |||
1564 | static int gn__pairs(lua_State *L) { | ||
1565 | lua_settop(L, 1); | ||
1566 | lua_pushinteger(L, 0); | ||
1567 | lua_pushcclosure(L, &gn__next, 2); | ||
1568 | |||
1569 | return 1; | ||
1570 | } /* gn__pairs() */ | ||
1571 | |||
1572 | |||
1573 | static int gn__gc(lua_State *L) { | ||
1574 | GENERAL_NAMES **ud = luaL_checkudata(L, 1, X509_GENS_CLASS); | ||
1575 | |||
1576 | sk_GENERAL_NAME_pop_free(*ud, GENERAL_NAME_free); | ||
1577 | *ud = NULL; | ||
1578 | |||
1579 | return 0; | ||
1580 | } /* gn__gc() */ | ||
1581 | |||
1582 | |||
1583 | static const luaL_Reg gn_methods[] = { | ||
1584 | { "add", &gn_add }, | ||
1585 | { NULL, NULL }, | ||
1586 | }; | ||
1587 | |||
1588 | static const luaL_Reg gn_metatable[] = { | ||
1589 | { "__pairs", &gn__pairs }, | ||
1590 | { "__gc", &gn__gc }, | ||
1591 | { NULL, NULL }, | ||
1592 | }; | ||
1593 | |||
1594 | |||
1595 | static const luaL_Reg gn_globals[] = { | ||
1596 | { "new", &gn_new }, | ||
1597 | { "interpose", &gn_interpose }, | ||
1598 | { NULL, NULL }, | ||
1599 | }; | ||
1600 | |||
1601 | int luaopen__openssl_x509_altname(lua_State *L) { | ||
1602 | initall(L); | ||
1603 | |||
1604 | luaL_newlib(L, gn_globals); | ||
1605 | |||
1606 | return 1; | ||
1607 | } /* luaopen__openssl_x509_altname() */ | ||
1608 | |||
1609 | |||
1610 | /* | ||
1611 | * X509 - openssl.x509.cert | ||
1612 | * | ||
1613 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
1614 | |||
1615 | static int xc_new(lua_State *L) { | ||
1616 | const char *pem; | ||
1617 | size_t len; | ||
1618 | X509 **ud; | ||
1619 | |||
1620 | lua_settop(L, 1); | ||
1621 | |||
1622 | ud = prepsimple(L, X509_CERT_CLASS); | ||
1623 | |||
1624 | if ((pem = luaL_optlstring(L, 1, NULL, &len))) { | ||
1625 | BIO *tmp; | ||
1626 | int ok; | ||
1627 | |||
1628 | if (!(tmp = BIO_new_mem_buf((char *)pem, len))) | ||
1629 | return throwssl(L, "x509.cert.new"); | ||
1630 | |||
1631 | ok = !!PEM_read_bio_X509(tmp, ud, 0, ""); /* no password */ | ||
1632 | |||
1633 | BIO_free(tmp); | ||
1634 | |||
1635 | if (!ok) | ||
1636 | return throwssl(L, "x509.cert.new"); | ||
1637 | } else { | ||
1638 | if (!(*ud = X509_new())) | ||
1639 | return throwssl(L, "x509.cert.new"); | ||
1640 | |||
1641 | X509_gmtime_adj(X509_get_notBefore(*ud), 0); | ||
1642 | X509_gmtime_adj(X509_get_notAfter(*ud), 0); | ||
1643 | } | ||
1644 | |||
1645 | return 1; | ||
1646 | } /* xc_new() */ | ||
1647 | |||
1648 | |||
1649 | static int xc_interpose(lua_State *L) { | ||
1650 | return interpose(L, X509_CERT_CLASS); | ||
1651 | } /* xc_interpose() */ | ||
1652 | |||
1653 | |||
1654 | static int xc_getVersion(lua_State *L) { | ||
1655 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
1656 | |||
1657 | lua_pushinteger(L, X509_get_version(crt) + 1); | ||
1658 | |||
1659 | return 1; | ||
1660 | } /* xc_getVersion() */ | ||
1661 | |||
1662 | |||
1663 | static int xc_setVersion(lua_State *L) { | ||
1664 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
1665 | int version = luaL_checkint(L, 2); | ||
1666 | |||
1667 | if (!X509_set_version(crt, version - 1)) | ||
1668 | return luaL_error(L, "x509.cert:setVersion: %d: invalid version", version); | ||
1669 | |||
1670 | lua_pushboolean(L, 1); | ||
1671 | |||
1672 | return 1; | ||
1673 | } /* xc_setVersion() */ | ||
1674 | |||
1675 | |||
1676 | static int xc_getSerial(lua_State *L) { | ||
1677 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
1678 | BIGNUM *serial = bn_push(L); | ||
1679 | ASN1_INTEGER *i; | ||
1680 | |||
1681 | if ((i = X509_get_serialNumber(crt))) { | ||
1682 | if (!ASN1_INTEGER_to_BN(i, serial)) | ||
1683 | return throwssl(L, "x509.cert:getSerial"); | ||
1684 | } | ||
1685 | |||
1686 | return 1; | ||
1687 | } /* xc_getSerial() */ | ||
1688 | |||
1689 | |||
1690 | static int xc_setSerial(lua_State *L) { | ||
1691 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
1692 | ASN1_INTEGER *serial; | ||
1693 | |||
1694 | if (!(serial = BN_to_ASN1_INTEGER(checkbig(L, 2), NULL))) | ||
1695 | goto error; | ||
1696 | |||
1697 | if (!X509_set_serialNumber(crt, serial)) | ||
1698 | goto error; | ||
1699 | |||
1700 | ASN1_INTEGER_free(serial); | ||
1701 | |||
1702 | lua_pushboolean(L, 1); | ||
1703 | |||
1704 | return 1; | ||
1705 | error: | ||
1706 | ASN1_INTEGER_free(serial); | ||
1707 | |||
1708 | return throwssl(L, "x509.cert:setSerial"); | ||
1709 | } /* xc_setSerial() */ | ||
1710 | |||
1711 | |||
1712 | static int xc_digest(lua_State *L) { | ||
1713 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
1714 | const char *type = luaL_optstring(L, 2, "sha1"); | ||
1715 | int format = luaL_checkoption(L, 3, "x", (const char *[]){ "s", "x", "n", NULL }); | ||
1716 | const EVP_MD *ctx; | ||
1717 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
1718 | unsigned len; | ||
1719 | |||
1720 | lua_settop(L, 3); /* self, type, hex */ | ||
1721 | |||
1722 | if (!(ctx = EVP_get_digestbyname(type))) | ||
1723 | return luaL_error(L, "x509.cert:digest: %s: invalid digest type", type); | ||
1724 | |||
1725 | X509_digest(crt, ctx, md, &len); | ||
1726 | |||
1727 | switch (format) { | ||
1728 | case 2: { | ||
1729 | BIGNUM *bn = bn_push(L); | ||
1730 | |||
1731 | if (!BN_bin2bn(md, len, bn)) | ||
1732 | return throwssl(L, "x509.cert:digest"); | ||
1733 | |||
1734 | break; | ||
1735 | } | ||
1736 | case 1: { | ||
1737 | static const unsigned char x[16] = "0123456789abcdef"; | ||
1738 | luaL_Buffer B; | ||
1739 | unsigned i; | ||
1740 | |||
1741 | #if LUA_VERSION_NUM < 502 | ||
1742 | luaL_buffinit(L, &B); | ||
1743 | #else | ||
1744 | luaL_buffinitsize(L, &B, 2 * len); | ||
1745 | #endif | ||
1746 | |||
1747 | for (i = 0; i < len; i++) { | ||
1748 | luaL_addchar(&B, x[0x0f & (md[i] >> 4)]); | ||
1749 | luaL_addchar(&B, x[0x0f & (md[i] >> 0)]); | ||
1750 | } | ||
1751 | |||
1752 | luaL_pushresult(&B); | ||
1753 | |||
1754 | break; | ||
1755 | } | ||
1756 | default: | ||
1757 | lua_pushlstring(L, (const char *)md, len); | ||
1758 | |||
1759 | break; | ||
1760 | } /* switch() */ | ||
1761 | |||
1762 | return 1; | ||
1763 | } /* xc_digest() */ | ||
1764 | |||
1765 | |||
1766 | static _Bool isleap(int year) { | ||
1767 | if (year >= 0) | ||
1768 | return !(year % 4) && ((year % 100) || !(year % 400)); | ||
1769 | else | ||
1770 | return isleap(-(year + 1)); | ||
1771 | } /* isleap() */ | ||
1772 | |||
1773 | |||
1774 | static int yday(int year, int mon, int mday) { | ||
1775 | static const int past[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; | ||
1776 | int yday = past[CLAMP(mon, 0, 11)] + CLAMP(mday, 1, 31) - 1; | ||
1777 | |||
1778 | return yday + (mon > 1 && isleap(year)); | ||
1779 | } /* yday() */ | ||
1780 | |||
1781 | |||
1782 | static int tm_yday(const struct tm *tm) { | ||
1783 | return (tm->tm_yday)? tm->tm_yday : yday(1900 + tm->tm_year, tm->tm_mon, tm->tm_mday); | ||
1784 | } /* tm_yday() */ | ||
1785 | |||
1786 | |||
1787 | static int leaps(int year) { | ||
1788 | if (year >= 0) | ||
1789 | return (year / 400) + (year / 4) - (year / 100); | ||
1790 | else | ||
1791 | return -(leaps(-(year + 1)) + 1); | ||
1792 | } /* leaps() */ | ||
1793 | |||
1794 | |||
1795 | static double tm2unix(const struct tm *tm, int gmtoff) { | ||
1796 | int year = tm->tm_year + 1900; | ||
1797 | double ts; | ||
1798 | |||
1799 | ts = 86400.0 * 365.0 * (year - 1970); | ||
1800 | ts += 86400.0 * (leaps(year - 1) - leaps(1969)); | ||
1801 | ts += 86400 * tm_yday(tm); | ||
1802 | ts += 3600 * tm->tm_hour; | ||
1803 | ts += 60 * tm->tm_min; | ||
1804 | ts += CLAMP(tm->tm_sec, 0, 59); | ||
1805 | ts += (year < 1970)? gmtoff : -gmtoff; | ||
1806 | |||
1807 | return ts; | ||
1808 | } /* tm2unix() */ | ||
1809 | |||
1810 | |||
1811 | static _Bool scan(int *i, char **cp, int n, int signok) { | ||
1812 | int sign = 1; | ||
1813 | |||
1814 | *i = 0; | ||
1815 | |||
1816 | if (signok) { | ||
1817 | if (**cp == '-') { | ||
1818 | sign = -1; | ||
1819 | ++*cp; | ||
1820 | } else if (**cp == '+') { | ||
1821 | ++*cp; | ||
1822 | } | ||
1823 | } | ||
1824 | |||
1825 | while (n-- > 0) { | ||
1826 | if (**cp < '0' || **cp > '9') | ||
1827 | return 0; | ||
1828 | |||
1829 | *i *= 10; | ||
1830 | *i += *(*cp)++ - '0'; | ||
1831 | } | ||
1832 | |||
1833 | *i *= sign; | ||
1834 | |||
1835 | return 1; | ||
1836 | } /* scan() */ | ||
1837 | |||
1838 | |||
1839 | static double timeutc(ASN1_TIME *time) { | ||
1840 | char buf[32] = "", *cp; | ||
1841 | struct tm tm = { 0 }; | ||
1842 | int gmtoff = 0, year, i; | ||
1843 | double ts; | ||
1844 | |||
1845 | if (!ASN1_TIME_check(time)) | ||
1846 | return 0; | ||
1847 | |||
1848 | cp = strncpy(buf, (const char *)ASN1_STRING_data((ASN1_STRING *)time), sizeof buf - 1); | ||
1849 | |||
1850 | if (ASN1_STRING_type(time) == V_ASN1_GENERALIZEDTIME) { | ||
1851 | if (!scan(&year, &cp, 4, 1)) | ||
1852 | goto badfmt; | ||
1853 | } else { | ||
1854 | if (!scan(&year, &cp, 2, 0)) | ||
1855 | goto badfmt; | ||
1856 | year += (year < 50)? 2000 : 1999; | ||
1857 | } | ||
1858 | |||
1859 | tm.tm_year = year - 1900; | ||
1860 | |||
1861 | if (!scan(&i, &cp, 2, 0)) | ||
1862 | goto badfmt; | ||
1863 | |||
1864 | tm.tm_mon = CLAMP(i, 1, 12) - 1; | ||
1865 | |||
1866 | if (!scan(&i, &cp, 2, 0)) | ||
1867 | goto badfmt; | ||
1868 | |||
1869 | tm.tm_mday = CLAMP(i, 1, 31); | ||
1870 | |||
1871 | tm.tm_yday = yday(year, tm.tm_mon, tm.tm_mday); | ||
1872 | |||
1873 | if (!scan(&i, &cp, 2, 0)) | ||
1874 | goto badfmt; | ||
1875 | |||
1876 | tm.tm_hour = CLAMP(i, 0, 23); | ||
1877 | |||
1878 | if (!scan(&i, &cp, 2, 0)) | ||
1879 | goto badfmt; | ||
1880 | |||
1881 | tm.tm_min = CLAMP(i, 0, 59); | ||
1882 | |||
1883 | if (*cp >= '0' && *cp <= '9') { | ||
1884 | if (!scan(&i, &cp, 2, 0)) | ||
1885 | goto badfmt; | ||
1886 | |||
1887 | tm.tm_sec = CLAMP(i, 0, 59); | ||
1888 | } | ||
1889 | |||
1890 | if (*cp == '+' || *cp == '-') { | ||
1891 | int sign = (*cp++ == '-')? -1 : 1; | ||
1892 | int hh, mm; | ||
1893 | |||
1894 | if (!scan(&hh, &cp, 2, 0) || !scan(&mm, &cp, 2, 0)) | ||
1895 | goto badfmt; | ||
1896 | |||
1897 | gmtoff = (CLAMP(hh, 0, 23) * 3600) | ||
1898 | + (CLAMP(mm, 0, 59) * 60); | ||
1899 | |||
1900 | gmtoff *= sign; | ||
1901 | } | ||
1902 | |||
1903 | return tm2unix(&tm, gmtoff); | ||
1904 | badfmt: | ||
1905 | return INFINITY; | ||
1906 | } /* timeutc() */ | ||
1907 | |||
1908 | |||
1909 | static int xc_getLifetime(lua_State *L) { | ||
1910 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
1911 | double begin = INFINITY, end = INFINITY; | ||
1912 | ASN1_TIME *time; | ||
1913 | |||
1914 | if ((time = X509_get_notBefore(crt))) | ||
1915 | begin = timeutc(time); | ||
1916 | |||
1917 | if ((time = X509_get_notAfter(crt))) | ||
1918 | end = timeutc(time); | ||
1919 | |||
1920 | if (isfinite(begin)) | ||
1921 | lua_pushnumber(L, begin); | ||
1922 | else | ||
1923 | lua_pushnil(L); | ||
1924 | |||
1925 | if (isfinite(end)) | ||
1926 | lua_pushnumber(L, end); | ||
1927 | else | ||
1928 | lua_pushnil(L); | ||
1929 | |||
1930 | if (isfinite(begin) && isfinite(end) && begin <= end) | ||
1931 | lua_pushnumber(L, fabs(end - begin)); | ||
1932 | else | ||
1933 | lua_pushnumber(L, 0.0); | ||
1934 | |||
1935 | return 3; | ||
1936 | } /* xc_getLifetime() */ | ||
1937 | |||
1938 | |||
1939 | static int xc_setLifetime(lua_State *L) { | ||
1940 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
1941 | ASN1_TIME *time; | ||
1942 | double ut; | ||
1943 | const char *dt; | ||
1944 | |||
1945 | lua_settop(L, 3); | ||
1946 | |||
1947 | if (lua_isnumber(L, 2)) { | ||
1948 | ut = lua_tonumber(L, 2); | ||
1949 | |||
1950 | if (!ASN1_TIME_set(X509_get_notBefore(crt), ut)) | ||
1951 | return throwssl(L, "x509.cert:setLifetime"); | ||
1952 | #if 0 | ||
1953 | } else if ((dt = luaL_optstring(L, 2, 0))) { | ||
1954 | if (!ASN1_TIME_set_string(X509_get_notBefore(crt), dt)) | ||
1955 | return throwssl(L, "x509.cert:setLifetime"); | ||
1956 | #endif | ||
1957 | } | ||
1958 | |||
1959 | if (lua_isnumber(L, 3)) { | ||
1960 | ut = lua_tonumber(L, 3); | ||
1961 | |||
1962 | if (!ASN1_TIME_set(X509_get_notAfter(crt), ut)) | ||
1963 | return throwssl(L, "x509.cert:setLifetime"); | ||
1964 | #if 0 | ||
1965 | } else if ((dt = luaL_optstring(L, 3, 0))) { | ||
1966 | if (!ASN1_TIME_set_string(X509_get_notAfter(crt), dt)) | ||
1967 | return throwssl(L, "x509.cert:setLifetime"); | ||
1968 | #endif | ||
1969 | } | ||
1970 | |||
1971 | lua_pushboolean(L, 1); | ||
1972 | |||
1973 | return 1; | ||
1974 | } /* xc_setLifetime() */ | ||
1975 | |||
1976 | |||
1977 | static int xc_getIssuer(lua_State *L) { | ||
1978 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
1979 | X509_NAME *name; | ||
1980 | |||
1981 | if (!(name = X509_get_issuer_name(crt))) | ||
1982 | return 0; | ||
1983 | |||
1984 | xn_dup(L, name); | ||
1985 | |||
1986 | return 1; | ||
1987 | } /* xc_getIssuer() */ | ||
1988 | |||
1989 | |||
1990 | static int xc_setIssuer(lua_State *L) { | ||
1991 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
1992 | X509_NAME *name = checksimple(L, 2, X509_NAME_CLASS); | ||
1993 | |||
1994 | if (!X509_set_issuer_name(crt, name)) | ||
1995 | return throwssl(L, "x509.cert:setIssuer"); | ||
1996 | |||
1997 | lua_pushboolean(L, 1); | ||
1998 | |||
1999 | return 1; | ||
2000 | } /* xc_setIssuer() */ | ||
2001 | |||
2002 | |||
2003 | static int xc_getSubject(lua_State *L) { | ||
2004 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2005 | X509_NAME *name; | ||
2006 | |||
2007 | if (!(name = X509_get_subject_name(crt))) | ||
2008 | return 0; | ||
2009 | |||
2010 | xn_dup(L, name); | ||
2011 | |||
2012 | return 1; | ||
2013 | } /* xc_getSubject() */ | ||
2014 | |||
2015 | |||
2016 | static int xc_setSubject(lua_State *L) { | ||
2017 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2018 | X509_NAME *name = checksimple(L, 2, X509_NAME_CLASS); | ||
2019 | |||
2020 | if (!X509_set_subject_name(crt, name)) | ||
2021 | return throwssl(L, "x509.cert:setSubject"); | ||
2022 | |||
2023 | lua_pushboolean(L, 1); | ||
2024 | |||
2025 | return 1; | ||
2026 | } /* xc_setSubject() */ | ||
2027 | |||
2028 | |||
2029 | static void xc_setCritical(X509 *crt, int nid, _Bool yes) { | ||
2030 | X509_EXTENSION *ext; | ||
2031 | int loc; | ||
2032 | |||
2033 | if ((loc = X509_get_ext_by_NID(crt, nid, -1)) >= 0 | ||
2034 | && (ext = X509_get_ext(crt, loc))) | ||
2035 | X509_EXTENSION_set_critical(ext, yes); | ||
2036 | } /* xc_setCritical() */ | ||
2037 | |||
2038 | |||
2039 | static _Bool xc_getCritical(X509 *crt, int nid) { | ||
2040 | X509_EXTENSION *ext; | ||
2041 | int loc; | ||
2042 | |||
2043 | if ((loc = X509_get_ext_by_NID(crt, nid, -1)) >= 0 | ||
2044 | && (ext = X509_get_ext(crt, loc))) | ||
2045 | return X509_EXTENSION_get_critical(ext); | ||
2046 | else | ||
2047 | return 0; | ||
2048 | } /* xc_getCritical() */ | ||
2049 | |||
2050 | |||
2051 | static int xc_getIssuerAlt(lua_State *L) { | ||
2052 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2053 | GENERAL_NAMES *gens; | ||
2054 | |||
2055 | if (!(gens = X509_get_ext_d2i(crt, NID_issuer_alt_name, 0, 0))) | ||
2056 | return 0; | ||
2057 | |||
2058 | gn_dup(L, gens); | ||
2059 | |||
2060 | return 1; | ||
2061 | } /* xc_getIssuerAlt() */ | ||
2062 | |||
2063 | |||
2064 | static int xc_setIssuerAlt(lua_State *L) { | ||
2065 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2066 | GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS); | ||
2067 | |||
2068 | if (!X509_add1_ext_i2d(crt, NID_issuer_alt_name, gens, 0, X509V3_ADD_REPLACE)) | ||
2069 | return throwssl(L, "x509.altname:setIssuerAlt"); | ||
2070 | |||
2071 | lua_pushboolean(L, 1); | ||
2072 | |||
2073 | return 1; | ||
2074 | } /* xc_setIssuerAlt() */ | ||
2075 | |||
2076 | |||
2077 | static int xc_getSubjectAlt(lua_State *L) { | ||
2078 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2079 | GENERAL_NAMES *gens; | ||
2080 | |||
2081 | if (!(gens = X509_get_ext_d2i(crt, NID_subject_alt_name, 0, 0))) | ||
2082 | return 0; | ||
2083 | |||
2084 | gn_dup(L, gens); | ||
2085 | |||
2086 | return 1; | ||
2087 | } /* xc_getSubjectAlt() */ | ||
2088 | |||
2089 | |||
2090 | static int xc_setSubjectAlt(lua_State *L) { | ||
2091 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2092 | GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS); | ||
2093 | |||
2094 | if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, X509V3_ADD_REPLACE)) | ||
2095 | return throwssl(L, "x509.altname:setSubjectAlt"); | ||
2096 | |||
2097 | lua_pushboolean(L, 1); | ||
2098 | |||
2099 | return 1; | ||
2100 | } /* xc_setSubjectAlt() */ | ||
2101 | |||
2102 | |||
2103 | static int xc_getIssuerAltCritical(lua_State *L) { | ||
2104 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2105 | |||
2106 | lua_pushboolean(L, xc_getCritical(crt, NID_issuer_alt_name)); | ||
2107 | |||
2108 | return 1; | ||
2109 | } /* xc_getIssuerAltCritical() */ | ||
2110 | |||
2111 | |||
2112 | static int xc_setIssuerAltCritical(lua_State *L) { | ||
2113 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2114 | |||
2115 | luaL_checkany(L, 2); | ||
2116 | xc_setCritical(crt, NID_issuer_alt_name, lua_toboolean(L, 2)); | ||
2117 | |||
2118 | lua_pushboolean(L, 1); | ||
2119 | |||
2120 | return 1; | ||
2121 | } /* xc_setIssuerAltCritical() */ | ||
2122 | |||
2123 | |||
2124 | static int xc_getSubjectAltCritical(lua_State *L) { | ||
2125 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2126 | |||
2127 | lua_pushboolean(L, xc_getCritical(crt, NID_subject_alt_name)); | ||
2128 | |||
2129 | return 1; | ||
2130 | } /* xc_getSubjectAltCritical() */ | ||
2131 | |||
2132 | |||
2133 | static int xc_setSubjectAltCritical(lua_State *L) { | ||
2134 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2135 | |||
2136 | luaL_checkany(L, 2); | ||
2137 | xc_setCritical(crt, NID_subject_alt_name, lua_toboolean(L, 2)); | ||
2138 | |||
2139 | lua_pushboolean(L, 1); | ||
2140 | |||
2141 | return 1; | ||
2142 | } /* xc_setSubjectAltCritical() */ | ||
2143 | |||
2144 | |||
2145 | static int xc_getBasicConstraint(lua_State *L) { | ||
2146 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2147 | BASIC_CONSTRAINTS *bs; | ||
2148 | int CA, pathLen; | ||
2149 | |||
2150 | if (!(bs = X509_get_ext_d2i(crt, NID_basic_constraints, 0, 0))) { | ||
2151 | /* FIXME: detect error or just non-existent */ | ||
2152 | |||
2153 | if (lua_gettop(L) > 1) | ||
2154 | return 0; | ||
2155 | |||
2156 | lua_newtable(L); | ||
2157 | |||
2158 | return 1; | ||
2159 | } | ||
2160 | |||
2161 | CA = bs->ca; | ||
2162 | pathLen = ASN1_INTEGER_get(bs->pathlen); | ||
2163 | |||
2164 | BASIC_CONSTRAINTS_free(bs); | ||
2165 | |||
2166 | if (lua_gettop(L) > 1) { | ||
2167 | int n = 0, i, top; | ||
2168 | |||
2169 | for (i = 2, top = lua_gettop(L); i <= top; i++) { | ||
2170 | switch (checkoption(L, i, 0, (const char *[]){ "CA", "pathLen", "pathLenConstraint", NULL })) { | ||
2171 | case 0: | ||
2172 | lua_pushboolean(L, CA); | ||
2173 | n++; | ||
2174 | break; | ||
2175 | case 1: | ||
2176 | /* FALL THROUGH */ | ||
2177 | case 2: | ||
2178 | lua_pushinteger(L, pathLen); | ||
2179 | n++; | ||
2180 | break; | ||
2181 | } | ||
2182 | } | ||
2183 | |||
2184 | return n; | ||
2185 | } else { | ||
2186 | lua_newtable(L); | ||
2187 | |||
2188 | lua_pushboolean(L, CA); | ||
2189 | lua_setfield(L, -2, "CA"); | ||
2190 | |||
2191 | lua_pushinteger(L, pathLen); | ||
2192 | lua_setfield(L, -2, "pathLen"); | ||
2193 | |||
2194 | return 1; | ||
2195 | } | ||
2196 | } /* xc_getBasicConstraint() */ | ||
2197 | |||
2198 | |||
2199 | static int xc_setBasicConstraint(lua_State *L) { | ||
2200 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2201 | BASIC_CONSTRAINTS *bs = 0; | ||
2202 | int CA = -1, pathLen = -1; | ||
2203 | int critical = 0; | ||
2204 | |||
2205 | luaL_checkany(L, 2); | ||
2206 | |||
2207 | if (lua_istable(L, 2)) { | ||
2208 | lua_getfield(L, 2, "CA"); | ||
2209 | if (!lua_isnil(L, -1)) | ||
2210 | CA = lua_toboolean(L, -1); | ||
2211 | lua_pop(L, 1); | ||
2212 | |||
2213 | lua_getfield(L, 2, "pathLen"); | ||
2214 | pathLen = luaL_optint(L, -1, pathLen); | ||
2215 | lua_pop(L, 1); | ||
2216 | |||
2217 | lua_getfield(L, 2, "pathLenConstraint"); | ||
2218 | pathLen = luaL_optint(L, -1, pathLen); | ||
2219 | lua_pop(L, 1); | ||
2220 | |||
2221 | if (!(bs = BASIC_CONSTRAINTS_new())) | ||
2222 | goto error; | ||
2223 | } else { | ||
2224 | lua_settop(L, 3); | ||
2225 | |||
2226 | switch (checkoption(L, 2, 0, (const char *[]){ "CA", "pathLen", "pathLenConstraint", NULL })) { | ||
2227 | case 0: | ||
2228 | luaL_checktype(L, 3, LUA_TBOOLEAN); | ||
2229 | CA = lua_toboolean(L, 3); | ||
2230 | |||
2231 | break; | ||
2232 | case 1: | ||
2233 | /* FALL THROUGH */ | ||
2234 | case 2: | ||
2235 | pathLen = luaL_checkint(L, 3); | ||
2236 | |||
2237 | break; | ||
2238 | } | ||
2239 | |||
2240 | if (!(bs = X509_get_ext_d2i(crt, NID_basic_constraints, &critical, 0))) { | ||
2241 | /* FIXME: detect whether error or just non-existent */ | ||
2242 | if (!(bs = BASIC_CONSTRAINTS_new())) | ||
2243 | goto error; | ||
2244 | } | ||
2245 | } | ||
2246 | |||
2247 | if (CA != -1) | ||
2248 | bs->ca = CA; | ||
2249 | |||
2250 | if (pathLen >= 0) { | ||
2251 | ASN1_INTEGER_free(bs->pathlen); | ||
2252 | |||
2253 | if (!(bs->pathlen = M_ASN1_INTEGER_new())) | ||
2254 | goto error; | ||
2255 | |||
2256 | if (!ASN1_INTEGER_set(bs->pathlen, pathLen)) | ||
2257 | goto error; | ||
2258 | } | ||
2259 | |||
2260 | if (!X509_add1_ext_i2d(crt, NID_basic_constraints, bs, critical, X509V3_ADD_REPLACE)) | ||
2261 | goto error; | ||
2262 | |||
2263 | BASIC_CONSTRAINTS_free(bs); | ||
2264 | |||
2265 | lua_pushboolean(L, 1); | ||
2266 | |||
2267 | return 1; | ||
2268 | error: | ||
2269 | BASIC_CONSTRAINTS_free(bs); | ||
2270 | |||
2271 | return throwssl(L, "x509.cert:setBasicConstraint"); | ||
2272 | } /* xc_setBasicConstraint() */ | ||
2273 | |||
2274 | |||
2275 | static int xc_getBasicConstraintsCritical(lua_State *L) { | ||
2276 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2277 | |||
2278 | lua_pushboolean(L, xc_getCritical(crt, NID_basic_constraints)); | ||
2279 | |||
2280 | return 1; | ||
2281 | } /* xc_getBasicConstraintsCritical() */ | ||
2282 | |||
2283 | |||
2284 | static int xc_setBasicConstraintsCritical(lua_State *L) { | ||
2285 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2286 | |||
2287 | luaL_checkany(L, 2); | ||
2288 | xc_setCritical(crt, NID_basic_constraints, lua_toboolean(L, 2)); | ||
2289 | |||
2290 | lua_pushboolean(L, 1); | ||
2291 | |||
2292 | return 1; | ||
2293 | } /* xc_setBasicConstraintsCritical() */ | ||
2294 | |||
2295 | |||
2296 | static int xc_isIssuedBy(lua_State *L) { | ||
2297 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2298 | X509 *issuer = checksimple(L, 2, X509_CERT_CLASS); | ||
2299 | EVP_PKEY *key; | ||
2300 | int ok, why = 0; | ||
2301 | |||
2302 | ERR_clear_error(); | ||
2303 | |||
2304 | if (X509_V_OK != (why = X509_check_issued(issuer, crt))) | ||
2305 | goto done; | ||
2306 | |||
2307 | if (!(key = X509_get_pubkey(issuer))) { | ||
2308 | why = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; | ||
2309 | goto done; | ||
2310 | } | ||
2311 | |||
2312 | ok = (1 == X509_verify(crt, key)); | ||
2313 | |||
2314 | EVP_PKEY_free(key); | ||
2315 | |||
2316 | if (!ok) | ||
2317 | why = X509_V_ERR_CERT_SIGNATURE_FAILURE; | ||
2318 | |||
2319 | done: | ||
2320 | if (why != X509_V_OK) { | ||
2321 | lua_pushboolean(L, 0); | ||
2322 | lua_pushstring(L, X509_verify_cert_error_string(why)); | ||
2323 | |||
2324 | return 2; | ||
2325 | } else { | ||
2326 | lua_pushboolean(L, 1); | ||
2327 | |||
2328 | return 1; | ||
2329 | } | ||
2330 | } /* xc_isIssuedBy() */ | ||
2331 | |||
2332 | |||
2333 | static int xc_getPublicKey(lua_State *L) { | ||
2334 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2335 | EVP_PKEY **key = prepsimple(L, PUBKEY_CLASS); | ||
2336 | |||
2337 | if (!(*key = X509_get_pubkey(crt))) | ||
2338 | return throwssl(L, "x509.cert:getPublicKey"); | ||
2339 | |||
2340 | return 1; | ||
2341 | } /* xc_getPublicKey() */ | ||
2342 | |||
2343 | |||
2344 | static int xc_setPublicKey(lua_State *L) { | ||
2345 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2346 | EVP_PKEY *key = checksimple(L, 2, PUBKEY_CLASS); | ||
2347 | |||
2348 | if (!X509_set_pubkey(crt, key)) | ||
2349 | return throwssl(L, "x509.cert:setPublicKey"); | ||
2350 | |||
2351 | lua_pushboolean(L, 1); | ||
2352 | |||
2353 | return 1; | ||
2354 | } /* xc_setPublicKey() */ | ||
2355 | |||
2356 | |||
2357 | static const EVP_MD *xc_signature(lua_State *L, int index, EVP_PKEY *key) { | ||
2358 | const char *id; | ||
2359 | const EVP_MD *md; | ||
2360 | |||
2361 | if ((id = luaL_optstring(L, index, NULL))) | ||
2362 | return ((md = EVP_get_digestbyname(id)))? md : EVP_md_null(); | ||
2363 | |||
2364 | switch (EVP_PKEY_type(key->type)) { | ||
2365 | case EVP_PKEY_RSA: | ||
2366 | return EVP_sha1(); | ||
2367 | case EVP_PKEY_DSA: | ||
2368 | return EVP_dss1(); | ||
2369 | case EVP_PKEY_EC: | ||
2370 | return EVP_ecdsa(); | ||
2371 | default: | ||
2372 | return EVP_md_null(); | ||
2373 | } | ||
2374 | } /* xc_signature() */ | ||
2375 | |||
2376 | static int xc_sign(lua_State *L) { | ||
2377 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2378 | EVP_PKEY *key = checksimple(L, 2, PUBKEY_CLASS); | ||
2379 | |||
2380 | if (!X509_sign(crt, key, xc_signature(L, 3, key))) | ||
2381 | return throwssl(L, "x509.cert:sign"); | ||
2382 | |||
2383 | lua_pushboolean(L, 1); | ||
2384 | |||
2385 | return 1; | ||
2386 | } /* xc_sign() */ | ||
2387 | |||
2388 | |||
2389 | static int xc__tostring(lua_State *L) { | ||
2390 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
2391 | int fmt = checkoption(L, 2, "pem", (const char *[]){ "pem", NULL }); | ||
2392 | BIO *bio = getbio(L); | ||
2393 | char *pem; | ||
2394 | long len; | ||
2395 | |||
2396 | if (!PEM_write_bio_X509(bio, crt)) | ||
2397 | return throwssl(L, "x509.cert:__tostring"); | ||
2398 | |||
2399 | len = BIO_get_mem_data(bio, &pem); | ||
2400 | |||
2401 | lua_pushlstring(L, pem, len); | ||
2402 | |||
2403 | return 1; | ||
2404 | } /* xc__tostring() */ | ||
2405 | |||
2406 | |||
2407 | static int xc__gc(lua_State *L) { | ||
2408 | X509 **ud = luaL_checkudata(L, 1, X509_CERT_CLASS); | ||
2409 | |||
2410 | X509_free(*ud); | ||
2411 | *ud = NULL; | ||
2412 | |||
2413 | return 0; | ||
2414 | } /* xc__gc() */ | ||
2415 | |||
2416 | |||
2417 | static const luaL_Reg xc_methods[] = { | ||
2418 | { "getVersion", &xc_getVersion }, | ||
2419 | { "setVersion", &xc_setVersion }, | ||
2420 | { "getSerial", &xc_getSerial }, | ||
2421 | { "setSerial", &xc_setSerial }, | ||
2422 | { "digest", &xc_digest }, | ||
2423 | { "getLifetime", &xc_getLifetime }, | ||
2424 | { "setLifetime", &xc_setLifetime }, | ||
2425 | { "getIssuer", &xc_getIssuer }, | ||
2426 | { "setIssuer", &xc_setIssuer }, | ||
2427 | { "getSubject", &xc_getSubject }, | ||
2428 | { "setSubject", &xc_setSubject }, | ||
2429 | { "getIssuerAlt", &xc_getIssuerAlt }, | ||
2430 | { "setIssuerAlt", &xc_setIssuerAlt }, | ||
2431 | { "getSubjectAlt", &xc_getSubjectAlt }, | ||
2432 | { "setSubjectAlt", &xc_setSubjectAlt }, | ||
2433 | { "getIssuerAltCritical", &xc_getIssuerAltCritical }, | ||
2434 | { "setIssuerAltCritical", &xc_setIssuerAltCritical }, | ||
2435 | { "getSubjectAltCritical", &xc_getSubjectAltCritical }, | ||
2436 | { "setSubjectAltCritical", &xc_setSubjectAltCritical }, | ||
2437 | { "getBasicConstraints", &xc_getBasicConstraint }, | ||
2438 | { "getBasicConstraint", &xc_getBasicConstraint }, | ||
2439 | { "setBasicConstraints", &xc_setBasicConstraint }, | ||
2440 | { "setBasicConstraint", &xc_setBasicConstraint }, | ||
2441 | { "getBasicConstraintsCritical", &xc_getBasicConstraintsCritical }, | ||
2442 | { "setBasicConstraintsCritical", &xc_setBasicConstraintsCritical }, | ||
2443 | { "isIssuedBy", &xc_isIssuedBy }, | ||
2444 | { "getPublicKey", &xc_getPublicKey }, | ||
2445 | { "setPublicKey", &xc_setPublicKey }, | ||
2446 | { "sign", &xc_sign }, | ||
2447 | { NULL, NULL }, | ||
2448 | }; | ||
2449 | |||
2450 | static const luaL_Reg xc_metatable[] = { | ||
2451 | { "__tostring", &xc__tostring }, | ||
2452 | { "__gc", &xc__gc }, | ||
2453 | { NULL, NULL }, | ||
2454 | }; | ||
2455 | |||
2456 | |||
2457 | static const luaL_Reg xc_globals[] = { | ||
2458 | { "new", &xc_new }, | ||
2459 | { "interpose", &xc_interpose }, | ||
2460 | { NULL, NULL }, | ||
2461 | }; | ||
2462 | |||
2463 | int luaopen__openssl_x509_cert(lua_State *L) { | ||
2464 | initall(L); | ||
2465 | |||
2466 | luaL_newlib(L, xc_globals); | ||
2467 | |||
2468 | return 1; | ||
2469 | } /* luaopen__openssl_x509_cert() */ | ||
2470 | |||
2471 | |||
2472 | /* | ||
2473 | * X509_REQ - openssl.x509.csr | ||
2474 | * | ||
2475 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
2476 | |||
2477 | static int xr_new(lua_State *L) { | ||
2478 | const char *pem; | ||
2479 | size_t len; | ||
2480 | X509_REQ **ud; | ||
2481 | X509 *crt; | ||
2482 | |||
2483 | lua_settop(L, 1); | ||
2484 | |||
2485 | ud = prepsimple(L, X509_CSR_CLASS); | ||
2486 | |||
2487 | if ((crt = testsimple(L, 1, X509_CERT_CLASS))) { | ||
2488 | if (!(*ud = X509_to_X509_REQ(crt, 0, 0))) | ||
2489 | return throwssl(L, "x509.csr.new"); | ||
2490 | } else if ((pem = luaL_optlstring(L, 1, NULL, &len))) { | ||
2491 | BIO *tmp; | ||
2492 | int ok; | ||
2493 | |||
2494 | if (!(tmp = BIO_new_mem_buf((char *)pem, len))) | ||
2495 | return throwssl(L, "x509.csr.new"); | ||
2496 | |||
2497 | ok = !!PEM_read_bio_X509_REQ(tmp, ud, 0, ""); /* no password */ | ||
2498 | |||
2499 | BIO_free(tmp); | ||
2500 | |||
2501 | if (!ok) | ||
2502 | return throwssl(L, "x509.csr.new"); | ||
2503 | } else { | ||
2504 | if (!(*ud = X509_REQ_new())) | ||
2505 | return throwssl(L, "x509.csr.new"); | ||
2506 | } | ||
2507 | |||
2508 | return 1; | ||
2509 | } /* xr_new() */ | ||
2510 | |||
2511 | |||
2512 | static int xr_interpose(lua_State *L) { | ||
2513 | return interpose(L, X509_CSR_CLASS); | ||
2514 | } /* xr_interpose() */ | ||
2515 | |||
2516 | |||
2517 | static int xr_getVersion(lua_State *L) { | ||
2518 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2519 | |||
2520 | lua_pushinteger(L, X509_REQ_get_version(csr) + 1); | ||
2521 | |||
2522 | return 1; | ||
2523 | } /* xr_getVersion() */ | ||
2524 | |||
2525 | |||
2526 | static int xr_setVersion(lua_State *L) { | ||
2527 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2528 | int version = luaL_checkint(L, 2); | ||
2529 | |||
2530 | if (!X509_REQ_set_version(csr, version - 1)) | ||
2531 | return luaL_error(L, "x509.csr:setVersion: %d: invalid version", version); | ||
2532 | |||
2533 | lua_pushboolean(L, 1); | ||
2534 | |||
2535 | return 1; | ||
2536 | } /* xr_setVersion() */ | ||
2537 | |||
2538 | |||
2539 | static int xr_getSubject(lua_State *L) { | ||
2540 | X509_REQ *crt = checksimple(L, 1, X509_CSR_CLASS); | ||
2541 | X509_NAME *name; | ||
2542 | |||
2543 | if (!(name = X509_REQ_get_subject_name(crt))) | ||
2544 | return 0; | ||
2545 | |||
2546 | xn_dup(L, name); | ||
2547 | |||
2548 | return 1; | ||
2549 | } /* xr_getSubject() */ | ||
2550 | |||
2551 | |||
2552 | static int xr_setSubject(lua_State *L) { | ||
2553 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2554 | X509_NAME *name = checksimple(L, 2, X509_NAME_CLASS); | ||
2555 | |||
2556 | if (!X509_REQ_set_subject_name(csr, name)) | ||
2557 | return throwssl(L, "x509.csr:setSubject"); | ||
2558 | |||
2559 | lua_pushboolean(L, 1); | ||
2560 | |||
2561 | return 1; | ||
2562 | } /* xr_setSubject() */ | ||
2563 | |||
2564 | |||
2565 | static int xr_getPublicKey(lua_State *L) { | ||
2566 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2567 | EVP_PKEY **key = prepsimple(L, PUBKEY_CLASS); | ||
2568 | |||
2569 | if (!(*key = X509_REQ_get_pubkey(csr))) | ||
2570 | return throwssl(L, "x509.cert:getPublicKey"); | ||
2571 | |||
2572 | return 1; | ||
2573 | } /* xr_getPublicKey() */ | ||
2574 | |||
2575 | |||
2576 | static int xr_setPublicKey(lua_State *L) { | ||
2577 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2578 | EVP_PKEY *key = checksimple(L, 2, PUBKEY_CLASS); | ||
2579 | |||
2580 | if (!X509_REQ_set_pubkey(csr, key)) | ||
2581 | return throwssl(L, "x509.csr:setPublicKey"); | ||
2582 | |||
2583 | lua_pushboolean(L, 1); | ||
2584 | |||
2585 | return 1; | ||
2586 | } /* xr_setPublicKey() */ | ||
2587 | |||
2588 | |||
2589 | static int xr_sign(lua_State *L) { | ||
2590 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2591 | EVP_PKEY *key = checksimple(L, 2, PUBKEY_CLASS); | ||
2592 | |||
2593 | if (!X509_REQ_sign(csr, key, xc_signature(L, 3, key))) | ||
2594 | return throwssl(L, "x509.csr:sign"); | ||
2595 | |||
2596 | lua_pushboolean(L, 1); | ||
2597 | |||
2598 | return 1; | ||
2599 | } /* xr_sign() */ | ||
2600 | |||
2601 | |||
2602 | static int xr__tostring(lua_State *L) { | ||
2603 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | ||
2604 | int fmt = checkoption(L, 2, "pem", (const char *[]){ "pem", NULL }); | ||
2605 | BIO *bio = getbio(L); | ||
2606 | char *pem; | ||
2607 | long len; | ||
2608 | |||
2609 | if (!PEM_write_bio_X509_REQ(bio, csr)) | ||
2610 | return throwssl(L, "x509.csr:__tostring"); | ||
2611 | |||
2612 | len = BIO_get_mem_data(bio, &pem); | ||
2613 | |||
2614 | lua_pushlstring(L, pem, len); | ||
2615 | |||
2616 | return 1; | ||
2617 | } /* xr__tostring() */ | ||
2618 | |||
2619 | |||
2620 | static int xr__gc(lua_State *L) { | ||
2621 | X509_REQ **ud = luaL_checkudata(L, 1, X509_CSR_CLASS); | ||
2622 | |||
2623 | X509_REQ_free(*ud); | ||
2624 | *ud = NULL; | ||
2625 | |||
2626 | return 0; | ||
2627 | } /* xr__gc() */ | ||
2628 | |||
2629 | static const luaL_Reg xr_methods[] = { | ||
2630 | { "getVersion", &xr_getVersion }, | ||
2631 | { "setVersion", &xr_setVersion }, | ||
2632 | { "getSubject", &xr_getSubject }, | ||
2633 | { "setSubject", &xr_setSubject }, | ||
2634 | { "getPublicKey", &xr_getPublicKey }, | ||
2635 | { "setPublicKey", &xr_setPublicKey }, | ||
2636 | { "sign", &xr_sign }, | ||
2637 | { NULL, NULL }, | ||
2638 | }; | ||
2639 | |||
2640 | static const luaL_Reg xr_metatable[] = { | ||
2641 | { "__tostring", &xr__tostring }, | ||
2642 | { "__gc", &xr__gc }, | ||
2643 | { NULL, NULL }, | ||
2644 | }; | ||
2645 | |||
2646 | |||
2647 | static const luaL_Reg xr_globals[] = { | ||
2648 | { "new", &xr_new }, | ||
2649 | { "interpose", &xr_interpose }, | ||
2650 | { NULL, NULL }, | ||
2651 | }; | ||
2652 | |||
2653 | int luaopen__openssl_x509_csr(lua_State *L) { | ||
2654 | initall(L); | ||
2655 | |||
2656 | luaL_newlib(L, xr_globals); | ||
2657 | |||
2658 | return 1; | ||
2659 | } /* luaopen__openssl_x509_csr() */ | ||
2660 | |||
2661 | |||
2662 | /* | ||
2663 | * STACK_OF(X509) - openssl.x509.chain | ||
2664 | * | ||
2665 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
2666 | |||
2667 | static void xl_dup(lua_State *L, STACK_OF(X509) *src, _Bool copy) { | ||
2668 | STACK_OF(X509) **dst = prepsimple(L, X509_CHAIN_CLASS); | ||
2669 | X509 *crt; | ||
2670 | int i, n; | ||
2671 | |||
2672 | if (copy) { | ||
2673 | if (!(*dst = sk_X509_new_null())) | ||
2674 | goto error; | ||
2675 | |||
2676 | n = sk_X509_num(src); | ||
2677 | |||
2678 | for (i = 0; i < n; i++) { | ||
2679 | if (!(crt = sk_X509_value(src, i))) | ||
2680 | continue; | ||
2681 | |||
2682 | if (!(crt = X509_dup(crt))) | ||
2683 | goto error; | ||
2684 | |||
2685 | if (!sk_X509_push(*dst, crt)) { | ||
2686 | X509_free(crt); | ||
2687 | goto error; | ||
2688 | } | ||
2689 | } | ||
2690 | } else { | ||
2691 | if (!(*dst = sk_X509_dup(src))) | ||
2692 | goto error; | ||
2693 | |||
2694 | n = sk_X509_num(*dst); | ||
2695 | |||
2696 | for (i = 0; i < n; i++) { | ||
2697 | if (!(crt = sk_X509_value(*dst, i))) | ||
2698 | continue; | ||
2699 | CRYPTO_add(&crt->references, 1, CRYPTO_LOCK_X509); | ||
2700 | } | ||
2701 | } | ||
2702 | |||
2703 | return; | ||
2704 | error: | ||
2705 | throwssl(L, "sk_X509_dup"); | ||
2706 | } /* xl_dup() */ | ||
2707 | |||
2708 | |||
2709 | static int xl_new(lua_State *L) { | ||
2710 | STACK_OF(X509) **chain = prepsimple(L, X509_CHAIN_CLASS); | ||
2711 | |||
2712 | if (!(*chain = sk_X509_new_null())) | ||
2713 | return throwssl(L, "x509.chain.new"); | ||
2714 | |||
2715 | return 1; | ||
2716 | } /* xl_new() */ | ||
2717 | |||
2718 | |||
2719 | static int xl_interpose(lua_State *L) { | ||
2720 | return interpose(L, X509_CHAIN_CLASS); | ||
2721 | } /* xl_interpose() */ | ||
2722 | |||
2723 | |||
2724 | static int xl_add(lua_State *L) { | ||
2725 | STACK_OF(X509) *chain = checksimple(L, 1, X509_CHAIN_CLASS); | ||
2726 | X509 *crt = checksimple(L, 2, X509_CERT_CLASS); | ||
2727 | X509 *dup; | ||
2728 | |||
2729 | if (!(dup = X509_dup(crt))) | ||
2730 | return throwssl(L, "x509.chain:add"); | ||
2731 | |||
2732 | if (!sk_X509_push(chain, dup)) { | ||
2733 | X509_free(dup); | ||
2734 | return throwssl(L, "x509.chain:add"); | ||
2735 | } | ||
2736 | |||
2737 | lua_pushboolean(L, 1); | ||
2738 | |||
2739 | return 1; | ||
2740 | } /* xl_add() */ | ||
2741 | |||
2742 | |||
2743 | static int xl__next(lua_State *L) { | ||
2744 | STACK_OF(X509) *chain = checksimple(L, lua_upvalueindex(1), X509_CHAIN_CLASS); | ||
2745 | int i = lua_tointeger(L, lua_upvalueindex(2)); | ||
2746 | int n = sk_X509_num(chain); | ||
2747 | |||
2748 | lua_settop(L, 0); | ||
2749 | |||
2750 | while (i < n) { | ||
2751 | X509 *crt, **ret; | ||
2752 | |||
2753 | if (!(crt = sk_X509_value(chain, i++))) | ||
2754 | continue; | ||
2755 | |||
2756 | lua_pushinteger(L, i); | ||
2757 | |||
2758 | ret = prepsimple(L, X509_CERT_CLASS); | ||
2759 | |||
2760 | if (!(*ret = X509_dup(crt))) | ||
2761 | return throwssl(L, "x509.chain:__next"); | ||
2762 | |||
2763 | break; | ||
2764 | } | ||
2765 | |||
2766 | lua_pushinteger(L, i); | ||
2767 | lua_replace(L, lua_upvalueindex(2)); | ||
2768 | |||
2769 | return lua_gettop(L); | ||
2770 | } /* xl__next() */ | ||
2771 | |||
2772 | static int xl__pairs(lua_State *L) { | ||
2773 | lua_settop(L, 1); | ||
2774 | lua_pushinteger(L, 0); | ||
2775 | lua_pushcclosure(L, &xl__next, 2); | ||
2776 | |||
2777 | return 1; | ||
2778 | } /* xl__pairs() */ | ||
2779 | |||
2780 | |||
2781 | static int xl__gc(lua_State *L) { | ||
2782 | STACK_OF(X509) **chain = luaL_checkudata(L, 1, X509_CHAIN_CLASS); | ||
2783 | |||
2784 | sk_X509_pop_free(*chain, X509_free); | ||
2785 | *chain = NULL; | ||
2786 | |||
2787 | return 0; | ||
2788 | } /* xl__gc() */ | ||
2789 | |||
2790 | |||
2791 | static const luaL_Reg xl_methods[] = { | ||
2792 | { "add", &xl_add }, | ||
2793 | { NULL, NULL }, | ||
2794 | }; | ||
2795 | |||
2796 | static const luaL_Reg xl_metatable[] = { | ||
2797 | { "__pairs", &xl__pairs }, | ||
2798 | { "__ipairs", &xl__pairs }, | ||
2799 | { "__gc", &xl__gc }, | ||
2800 | { NULL, NULL }, | ||
2801 | }; | ||
2802 | |||
2803 | static const luaL_Reg xl_globals[] = { | ||
2804 | { "new", &xl_new }, | ||
2805 | { "interpose", &xl_interpose }, | ||
2806 | { NULL, NULL }, | ||
2807 | }; | ||
2808 | |||
2809 | int luaopen__openssl_x509_chain(lua_State *L) { | ||
2810 | initall(L); | ||
2811 | |||
2812 | luaL_newlib(L, xl_globals); | ||
2813 | |||
2814 | return 1; | ||
2815 | } /* luaopen__openssl_x509_chain() */ | ||
2816 | |||
2817 | |||
2818 | /* | ||
2819 | * X509_STORE - openssl.x509.store | ||
2820 | * | ||
2821 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
2822 | |||
2823 | static int xs_new(lua_State *L) { | ||
2824 | X509_STORE **ud = prepsimple(L, X509_STORE_CLASS); | ||
2825 | |||
2826 | if (!(*ud = X509_STORE_new())) | ||
2827 | return throwssl(L, "x509.store"); | ||
2828 | |||
2829 | return 1; | ||
2830 | } /* xs_new() */ | ||
2831 | |||
2832 | |||
2833 | static int xs_interpose(lua_State *L) { | ||
2834 | return interpose(L, X509_STORE_CLASS); | ||
2835 | } /* xs_interpose() */ | ||
2836 | |||
2837 | |||
2838 | static int xs_add(lua_State *L) { | ||
2839 | X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS); | ||
2840 | int i, top = lua_gettop(L); | ||
2841 | |||
2842 | for (i = 2; i <= top; i++) { | ||
2843 | if (lua_isuserdata(L, i)) { | ||
2844 | X509 *crt = checksimple(L, i, X509_CERT_CLASS); | ||
2845 | X509 *dup; | ||
2846 | |||
2847 | if (!(dup = X509_dup(crt))) | ||
2848 | return throwssl(L, "x509.store:add"); | ||
2849 | |||
2850 | if (!X509_STORE_add_cert(store, dup)) { | ||
2851 | X509_free(dup); | ||
2852 | return throwssl(L, "x509.store:add"); | ||
2853 | } | ||
2854 | } else { | ||
2855 | const char *path = luaL_checkstring(L, i); | ||
2856 | struct stat st; | ||
2857 | int ok; | ||
2858 | |||
2859 | if (0 != stat(path, &st)) | ||
2860 | return luaL_error(L, "%s: %s", path, strerror(errno)); | ||
2861 | |||
2862 | if (S_ISDIR(st.st_mode)) | ||
2863 | ok = X509_STORE_load_locations(store, NULL, path); | ||
2864 | else | ||
2865 | ok = X509_STORE_load_locations(store, path, NULL); | ||
2866 | |||
2867 | if (!ok) | ||
2868 | return throwssl(L, "x509.store:add"); | ||
2869 | } | ||
2870 | } | ||
2871 | |||
2872 | lua_pushboolean(L, 1); | ||
2873 | |||
2874 | return 1; | ||
2875 | } /* xs_add() */ | ||
2876 | |||
2877 | |||
2878 | static int xs_verify(lua_State *L) { | ||
2879 | X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS); | ||
2880 | X509 *crt = checksimple(L, 2, X509_CERT_CLASS); | ||
2881 | STACK_OF(X509) *chain = NULL, **proof; | ||
2882 | X509_STORE_CTX ctx; | ||
2883 | int ok, why; | ||
2884 | |||
2885 | /* pre-allocate space for a successful return */ | ||
2886 | lua_settop(L, 3); | ||
2887 | proof = prepsimple(L, X509_CHAIN_CLASS); | ||
2888 | |||
2889 | if (!lua_isnoneornil(L, 3)) { | ||
2890 | X509 *elm; | ||
2891 | int i, n; | ||
2892 | |||
2893 | if (!(chain = sk_X509_dup(checksimple(L, 3, X509_CHAIN_CLASS)))) | ||
2894 | return throwssl(L, "x509.store:verify"); | ||
2895 | |||
2896 | n = sk_X509_num(chain); | ||
2897 | |||
2898 | for (i = 0; i < n; i++) { | ||
2899 | if (!(elm = sk_X509_value(chain, i))) | ||
2900 | continue; | ||
2901 | CRYPTO_add(&elm->references, 1, CRYPTO_LOCK_X509); | ||
2902 | } | ||
2903 | } | ||
2904 | |||
2905 | if (!X509_STORE_CTX_init(&ctx, store, crt, chain)) { | ||
2906 | sk_X509_pop_free(chain, X509_free); | ||
2907 | return throwssl(L, "x509.store:verify"); | ||
2908 | } | ||
2909 | |||
2910 | ERR_clear_error(); | ||
2911 | |||
2912 | ok = X509_verify_cert(&ctx); | ||
2913 | |||
2914 | switch (ok) { | ||
2915 | case 1: /* verified */ | ||
2916 | *proof = X509_STORE_CTX_get1_chain(&ctx); | ||
2917 | |||
2918 | X509_STORE_CTX_cleanup(&ctx); | ||
2919 | |||
2920 | if (!*proof) | ||
2921 | return throwssl(L, "x509.store:verify"); | ||
2922 | |||
2923 | lua_pushboolean(L, 1); | ||
2924 | lua_pushvalue(L, -2); | ||
2925 | |||
2926 | return 2; | ||
2927 | case 0: /* not verified */ | ||
2928 | why = X509_STORE_CTX_get_error(&ctx); | ||
2929 | |||
2930 | X509_STORE_CTX_cleanup(&ctx); | ||
2931 | |||
2932 | lua_pushboolean(L, 0); | ||
2933 | lua_pushstring(L, X509_verify_cert_error_string(why)); | ||
2934 | |||
2935 | return 2; | ||
2936 | default: | ||
2937 | X509_STORE_CTX_cleanup(&ctx); | ||
2938 | |||
2939 | return throwssl(L, "x509.store:verify"); | ||
2940 | } | ||
2941 | } /* xs_verify() */ | ||
2942 | |||
2943 | |||
2944 | static int xs__gc(lua_State *L) { | ||
2945 | X509_STORE **ud = luaL_checkudata(L, 1, X509_STORE_CLASS); | ||
2946 | |||
2947 | X509_STORE_free(*ud); | ||
2948 | *ud = NULL; | ||
2949 | |||
2950 | return 0; | ||
2951 | } /* xs__gc() */ | ||
2952 | |||
2953 | |||
2954 | static const luaL_Reg xs_methods[] = { | ||
2955 | { "add", &xs_add }, | ||
2956 | { "verify", &xs_verify }, | ||
2957 | { NULL, NULL }, | ||
2958 | }; | ||
2959 | |||
2960 | static const luaL_Reg xs_metatable[] = { | ||
2961 | { "__gc", &xs__gc }, | ||
2962 | { NULL, NULL }, | ||
2963 | }; | ||
2964 | |||
2965 | static const luaL_Reg xs_globals[] = { | ||
2966 | { "new", &xs_new }, | ||
2967 | { "interpose", &xs_interpose }, | ||
2968 | { NULL, NULL }, | ||
2969 | }; | ||
2970 | |||
2971 | int luaopen__openssl_x509_store(lua_State *L) { | ||
2972 | initall(L); | ||
2973 | |||
2974 | luaL_newlib(L, xs_globals); | ||
2975 | |||
2976 | return 1; | ||
2977 | } /* luaopen__openssl_x509_store() */ | ||
2978 | |||
2979 | |||
2980 | /* | ||
2981 | * X509_STORE_CTX - openssl.x509.store.context | ||
2982 | * | ||
2983 | * This object is intended to be a temporary container in OpenSSL, so the | ||
2984 | * memory management is quite clumsy. In particular, it doesn't take | ||
2985 | * ownership of the X509_STORE object, which means the reference must be | ||
2986 | * held externally for the life of the X509_STORE_CTX object. | ||
2987 | * | ||
2988 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
2989 | #if 0 | ||
2990 | static int stx_new(lua_State *L) { | ||
2991 | X509_STORE_CTX **ud = prepsimple(L, X509_STCTX_CLASS); | ||
2992 | STACK_OF(X509) *chain; | ||
2993 | |||
2994 | if (!(*ud = X509_STORE_CTX_new())) | ||
2995 | return throwssl(L, "x509.store.context"); | ||
2996 | |||
2997 | return 1; | ||
2998 | } /* stx_new() */ | ||
2999 | |||
3000 | |||
3001 | static int stx_interpose(lua_State *L) { | ||
3002 | return interpose(L, X509_STCTX_CLASS); | ||
3003 | } /* stx_interpose() */ | ||
3004 | |||
3005 | |||
3006 | static int stx_add(lua_State *L) { | ||
3007 | X509_STORE_CTX *ctx = checksimple(L, 1, X509_STCTX_CLASS); | ||
3008 | |||
3009 | return 0; | ||
3010 | } /* stx_add() */ | ||
3011 | |||
3012 | |||
3013 | static int stx__gc(lua_State *L) { | ||
3014 | X509_STORE **ud = luaL_checkudata(L, 1, X509_STORE_CLASS); | ||
3015 | |||
3016 | X509_STORE_free(*ud); | ||
3017 | *ud = NULL; | ||
3018 | |||
3019 | return 0; | ||
3020 | } /* stx__gc() */ | ||
3021 | |||
3022 | |||
3023 | static const luaL_Reg stx_methods[] = { | ||
3024 | { "add", &stx_add }, | ||
3025 | { NULL, NULL }, | ||
3026 | }; | ||
3027 | |||
3028 | static const luaL_Reg stx_metatable[] = { | ||
3029 | { "__gc", &stx__gc }, | ||
3030 | { NULL, NULL }, | ||
3031 | }; | ||
3032 | |||
3033 | static const luaL_Reg stx_globals[] = { | ||
3034 | { "new", &stx_new }, | ||
3035 | { "interpose", &stx_interpose }, | ||
3036 | { NULL, NULL }, | ||
3037 | }; | ||
3038 | |||
3039 | int luaopen__openssl_x509_store_context(lua_State *L) { | ||
3040 | initall(L); | ||
3041 | |||
3042 | luaL_newlib(L, stx_globals); | ||
3043 | |||
3044 | return 1; | ||
3045 | } /* luaopen__openssl_x509_store_context() */ | ||
3046 | #endif | ||
3047 | |||
3048 | |||
3049 | /* | ||
3050 | * SSL_CTX - openssl.ssl.context | ||
3051 | * | ||
3052 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
3053 | |||
3054 | static int sx_new(lua_State *L) { | ||
3055 | static const char *opts[] = { | ||
3056 | "SSLv2", "SSLv3", "SSLv23", "SSL", "TLSv1", "TLS", NULL | ||
3057 | }; | ||
3058 | /* later versions of SSL declare a const qualifier on the return type */ | ||
3059 | __typeof__(&TLSv1_client_method) method = &TLSv1_client_method; | ||
3060 | _Bool srv; | ||
3061 | SSL_CTX **ud; | ||
3062 | |||
3063 | lua_settop(L, 2); | ||
3064 | srv = lua_toboolean(L, 2); | ||
3065 | |||
3066 | switch (checkoption(L, 1, "TLS", opts)) { | ||
3067 | #ifndef OPENSSL_NO_SSL2 | ||
3068 | case 0: /* SSLv2 */ | ||
3069 | method = (srv)? &SSLv2_server_method : &SSLv2_client_method; | ||
3070 | break; | ||
3071 | #endif | ||
3072 | case 1: /* SSLv3 */ | ||
3073 | method = (srv)? &SSLv3_server_method : &SSLv3_client_method; | ||
3074 | break; | ||
3075 | case 2: /* SSLv23 */ | ||
3076 | /* FALL THROUGH */ | ||
3077 | case 3: /* SSL */ | ||
3078 | method = (srv)? &SSLv23_server_method : &SSLv23_client_method; | ||
3079 | break; | ||
3080 | case 4: /* TLSv1 */ | ||
3081 | /* FALL THROUGH */ | ||
3082 | case 5: /* TLS */ | ||
3083 | method = (srv)? &TLSv1_server_method : &TLSv1_client_method; | ||
3084 | break; | ||
3085 | } | ||
3086 | |||
3087 | ud = prepsimple(L, SSL_CTX_CLASS); | ||
3088 | |||
3089 | if (!(*ud = SSL_CTX_new(method()))) | ||
3090 | return throwssl(L, "ssl.context.new"); | ||
3091 | |||
3092 | return 1; | ||
3093 | } /* sx_new() */ | ||
3094 | |||
3095 | |||
3096 | static int sx_interpose(lua_State *L) { | ||
3097 | return interpose(L, SSL_CTX_CLASS); | ||
3098 | } /* sx_interpose() */ | ||
3099 | |||
3100 | |||
3101 | static int sx_setStore(lua_State *L) { | ||
3102 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
3103 | X509_STORE *store = checksimple(L, 2, X509_STORE_CLASS); | ||
3104 | |||
3105 | SSL_CTX_set_cert_store(ctx, store); | ||
3106 | CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); | ||
3107 | |||
3108 | lua_pushboolean(L, 1); | ||
3109 | |||
3110 | return 1; | ||
3111 | } /* sx_setStore() */ | ||
3112 | |||
3113 | |||
3114 | static int sx_setVerify(lua_State *L) { | ||
3115 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
3116 | int mode = luaL_optint(L, 2, -1); | ||
3117 | int depth = luaL_optint(L, 3, -1); | ||
3118 | |||
3119 | if (mode != -1) | ||
3120 | SSL_CTX_set_verify(ctx, mode, 0); | ||
3121 | |||
3122 | if (depth != -1) | ||
3123 | SSL_CTX_set_verify_depth(ctx, depth); | ||
3124 | |||
3125 | lua_pushboolean(L, 1); | ||
3126 | |||
3127 | return 1; | ||
3128 | } /* sx_setVerify() */ | ||
3129 | |||
3130 | |||
3131 | static int sx_getVerify(lua_State *L) { | ||
3132 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
3133 | |||
3134 | lua_pushinteger(L, SSL_CTX_get_verify_mode(ctx)); | ||
3135 | lua_pushinteger(L, SSL_CTX_get_verify_depth(ctx)); | ||
3136 | |||
3137 | return 2; | ||
3138 | } /* sx_getVerify() */ | ||
3139 | |||
3140 | |||
3141 | static int sx_setCertificate(lua_State *L) { | ||
3142 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
3143 | X509 *crt = X509_dup(checksimple(L, 2, X509_CERT_CLASS)); | ||
3144 | int ok; | ||
3145 | |||
3146 | ok = SSL_CTX_use_certificate(ctx, crt); | ||
3147 | X509_free(crt); | ||
3148 | |||
3149 | if (!ok) | ||
3150 | return throwssl(L, "ssl.context:setCertificate"); | ||
3151 | |||
3152 | lua_pushboolean(L, 1); | ||
3153 | |||
3154 | return 1; | ||
3155 | } /* sx_setCertificate() */ | ||
3156 | |||
3157 | |||
3158 | static int sx_setPrivateKey(lua_State *L) { | ||
3159 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
3160 | EVP_PKEY *key = checksimple(L, 2, PUBKEY_CLASS); | ||
3161 | |||
3162 | /* | ||
3163 | * NOTE: No easy way to dup the key, but a shared reference should | ||
3164 | * be okay as keys are less mutable than certificates. | ||
3165 | */ | ||
3166 | if (!SSL_CTX_use_PrivateKey(ctx, key)) | ||
3167 | return throwssl(L, "ssl.context:setPrivateKey"); | ||
3168 | |||
3169 | lua_pushboolean(L, 1); | ||
3170 | |||
3171 | return 1; | ||
3172 | } /* sx_setPrivateKey() */ | ||
3173 | |||
3174 | |||
3175 | static int sx_setCipherList(lua_State *L) { | ||
3176 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
3177 | const char *ciphers = luaL_checkstring(L, 2); | ||
3178 | |||
3179 | if (!SSL_CTX_set_cipher_list(ctx, ciphers)) | ||
3180 | return throwssl(L, "ssl.context:setCipherList"); | ||
3181 | |||
3182 | lua_pushboolean(L, 1); | ||
3183 | |||
3184 | return 1; | ||
3185 | } /* sx_setCipherList() */ | ||
3186 | |||
3187 | |||
3188 | static int sx__gc(lua_State *L) { | ||
3189 | SSL_CTX **ud = luaL_checkudata(L, 1, SSL_CTX_CLASS); | ||
3190 | |||
3191 | SSL_CTX_free(*ud); | ||
3192 | *ud = NULL; | ||
3193 | |||
3194 | return 0; | ||
3195 | } /* sx__gc() */ | ||
3196 | |||
3197 | |||
3198 | static const luaL_Reg sx_methods[] = { | ||
3199 | { "setStore", &sx_setStore }, | ||
3200 | { "setVerify", &sx_setVerify }, | ||
3201 | { "getVerify", &sx_getVerify }, | ||
3202 | { "setCertificate", &sx_setCertificate }, | ||
3203 | { "setPrivateKey", &sx_setPrivateKey }, | ||
3204 | { "setCipherList", &sx_setCipherList }, | ||
3205 | { NULL, NULL }, | ||
3206 | }; | ||
3207 | |||
3208 | static const luaL_Reg sx_metatable[] = { | ||
3209 | { "__gc", &sx__gc }, | ||
3210 | { NULL, NULL }, | ||
3211 | }; | ||
3212 | |||
3213 | static const luaL_Reg sx_globals[] = { | ||
3214 | { "new", &sx_new }, | ||
3215 | { "interpose", &sx_interpose }, | ||
3216 | { NULL, NULL }, | ||
3217 | }; | ||
3218 | |||
3219 | int luaopen__openssl_ssl_context(lua_State *L) { | ||
3220 | initall(L); | ||
3221 | |||
3222 | luaL_newlib(L, sx_globals); | ||
3223 | |||
3224 | lua_pushinteger(L, SSL_VERIFY_NONE); | ||
3225 | lua_setfield(L, -2, "VERIFY_NONE"); | ||
3226 | |||
3227 | lua_pushinteger(L, SSL_VERIFY_PEER); | ||
3228 | lua_setfield(L, -2, "VERIFY_PEER"); | ||
3229 | |||
3230 | lua_pushinteger(L, SSL_VERIFY_FAIL_IF_NO_PEER_CERT); | ||
3231 | lua_setfield(L, -2, "VERIFY_FAIL_IF_NO_PEER_CERT"); | ||
3232 | |||
3233 | lua_pushinteger(L, SSL_VERIFY_CLIENT_ONCE); | ||
3234 | lua_setfield(L, -2, "VERIFY_CLIENT_ONCE"); | ||
3235 | |||
3236 | return 1; | ||
3237 | } /* luaopen__openssl_ssl_context() */ | ||
3238 | |||
3239 | |||
3240 | /* | ||
3241 | * SSL - openssl.ssl | ||
3242 | * | ||
3243 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
3244 | |||
3245 | static int ssl_new(lua_State *L) { | ||
3246 | lua_pushnil(L); | ||
3247 | |||
3248 | return 1; | ||
3249 | } /* ssl_new() */ | ||
3250 | |||
3251 | |||
3252 | static int ssl_interpose(lua_State *L) { | ||
3253 | return interpose(L, SSL_CLASS); | ||
3254 | } /* ssl_interpose() */ | ||
3255 | |||
3256 | |||
3257 | static int ssl_getPeerCertificate(lua_State *L) { | ||
3258 | SSL *ssl = checksimple(L, 1, SSL_CLASS); | ||
3259 | X509 **x509 = prepsimple(L, X509_CERT_CLASS); | ||
3260 | |||
3261 | if (!(*x509 = SSL_get_peer_certificate(ssl))) | ||
3262 | return 0; | ||
3263 | |||
3264 | return 1; | ||
3265 | } /* ssl_getPeerCertificate() */ | ||
3266 | |||
3267 | |||
3268 | static int ssl_getPeerChain(lua_State *L) { | ||
3269 | SSL *ssl = checksimple(L, 1, SSL_CLASS); | ||
3270 | STACK_OF(X509) *chain; | ||
3271 | |||
3272 | if (!(chain = SSL_get_peer_cert_chain(ssl))) | ||
3273 | return 0; | ||
3274 | |||
3275 | xl_dup(L, chain, 0); | ||
3276 | |||
3277 | return 1; | ||
3278 | } /* ssl_getPeerChain() */ | ||
3279 | |||
3280 | |||
3281 | static int ssl_getCipherInfo(lua_State *L) { | ||
3282 | SSL *ssl = checksimple(L, 1, SSL_CLASS); | ||
3283 | const SSL_CIPHER *cipher; | ||
3284 | char descr[256]; | ||
3285 | |||
3286 | if (!(cipher = SSL_get_current_cipher(ssl))) | ||
3287 | return 0; | ||
3288 | |||
3289 | lua_newtable(L); | ||
3290 | |||
3291 | lua_pushstring(L, SSL_CIPHER_get_name(cipher)); | ||
3292 | lua_setfield(L, -2, "name"); | ||
3293 | |||
3294 | lua_pushinteger(L, SSL_CIPHER_get_bits(cipher, 0)); | ||
3295 | lua_setfield(L, -2, "bits"); | ||
3296 | |||
3297 | lua_pushstring(L, SSL_CIPHER_get_version(cipher)); | ||
3298 | lua_setfield(L, -2, "version"); | ||
3299 | |||
3300 | lua_pushstring(L, SSL_CIPHER_description(cipher, descr, sizeof descr)); | ||
3301 | lua_setfield(L, -2, "description"); | ||
3302 | |||
3303 | return 1; | ||
3304 | } /* ssl_getCipherInfo() */ | ||
3305 | |||
3306 | |||
3307 | static int ssl__gc(lua_State *L) { | ||
3308 | SSL **ud = luaL_checkudata(L, 1, SSL_CLASS); | ||
3309 | |||
3310 | SSL_free(*ud); | ||
3311 | *ud = NULL; | ||
3312 | |||
3313 | return 0; | ||
3314 | } /* ssl__gc() */ | ||
3315 | |||
3316 | |||
3317 | static const luaL_Reg ssl_methods[] = { | ||
3318 | { "getPeerCertificate", &ssl_getPeerCertificate }, | ||
3319 | { "getPeerChain", &ssl_getPeerChain }, | ||
3320 | { "getCipherInfo", &ssl_getCipherInfo }, | ||
3321 | { NULL, NULL }, | ||
3322 | }; | ||
3323 | |||
3324 | static const luaL_Reg ssl_metatable[] = { | ||
3325 | { "__gc", &ssl__gc }, | ||
3326 | { NULL, NULL }, | ||
3327 | }; | ||
3328 | |||
3329 | static const luaL_Reg ssl_globals[] = { | ||
3330 | { "new", &ssl_new }, | ||
3331 | { "interpose", &ssl_interpose }, | ||
3332 | { NULL, NULL }, | ||
3333 | }; | ||
3334 | |||
3335 | int luaopen__openssl_ssl(lua_State *L) { | ||
3336 | initall(L); | ||
3337 | |||
3338 | luaL_newlib(L, ssl_globals); | ||
3339 | |||
3340 | return 1; | ||
3341 | } /* luaopen__openssl_ssl() */ | ||
3342 | |||
3343 | |||
3344 | /* | ||
3345 | * Digest - openssl.digest | ||
3346 | * | ||
3347 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
3348 | |||
3349 | static const EVP_MD *md_optdigest(lua_State *L, int index) { | ||
3350 | const char *name = luaL_optstring(L, index, "sha1"); | ||
3351 | const EVP_MD *type; | ||
3352 | |||
3353 | if (!(type = EVP_get_digestbyname(name))) | ||
3354 | luaL_argerror(L, index, lua_pushfstring(L, "%s: invalid digest type", name)); | ||
3355 | |||
3356 | return type; | ||
3357 | } /* md_optdigest() */ | ||
3358 | |||
3359 | |||
3360 | static int md_new(lua_State *L) { | ||
3361 | const EVP_MD *type = md_optdigest(L, 1); | ||
3362 | EVP_MD_CTX *ctx; | ||
3363 | |||
3364 | ctx = prepudata(L, sizeof *ctx, DIGEST_CLASS, NULL); | ||
3365 | |||
3366 | EVP_MD_CTX_init(ctx); | ||
3367 | |||
3368 | if (!EVP_DigestInit_ex(ctx, type, NULL)) | ||
3369 | return throwssl(L, "digest.new"); | ||
3370 | |||
3371 | return 1; | ||
3372 | } /* md_new() */ | ||
3373 | |||
3374 | |||
3375 | static int md_interpose(lua_State *L) { | ||
3376 | return interpose(L, DIGEST_CLASS); | ||
3377 | } /* md_interpose() */ | ||
3378 | |||
3379 | |||
3380 | static void md_update_(lua_State *L, EVP_MD_CTX *ctx, int from, int to) { | ||
3381 | int i; | ||
3382 | |||
3383 | for (i = from; i <= to; i++) { | ||
3384 | const void *p; | ||
3385 | size_t n; | ||
3386 | |||
3387 | p = luaL_checklstring(L, i, &n); | ||
3388 | |||
3389 | if (!EVP_DigestUpdate(ctx, p, n)) | ||
3390 | throwssl(L, "digest:update"); | ||
3391 | } | ||
3392 | } /* md_update_() */ | ||
3393 | |||
3394 | |||
3395 | static int md_update(lua_State *L) { | ||
3396 | EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS); | ||
3397 | int i, top = lua_gettop(L); | ||
3398 | |||
3399 | md_update_(L, ctx, 2, lua_gettop(L)); | ||
3400 | |||
3401 | lua_pushboolean(L, 1); | ||
3402 | |||
3403 | return 1; | ||
3404 | } /* md_update() */ | ||
3405 | |||
3406 | |||
3407 | static int md_final(lua_State *L) { | ||
3408 | EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS); | ||
3409 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
3410 | unsigned len; | ||
3411 | |||
3412 | md_update_(L, ctx, 2, lua_gettop(L)); | ||
3413 | |||
3414 | if (!EVP_DigestFinal_ex(ctx, md, &len)) | ||
3415 | return throwssl(L, "digest:final"); | ||
3416 | |||
3417 | lua_pushlstring(L, (char *)md, len); | ||
3418 | |||
3419 | return 1; | ||
3420 | } /* md_final() */ | ||
3421 | |||
3422 | |||
3423 | static int md__gc(lua_State *L) { | ||
3424 | EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS); | ||
3425 | |||
3426 | EVP_MD_CTX_cleanup(ctx); | ||
3427 | |||
3428 | return 0; | ||
3429 | } /* md__gc() */ | ||
3430 | |||
3431 | |||
3432 | static const luaL_Reg md_methods[] = { | ||
3433 | { "update", &md_update }, | ||
3434 | { "final", &md_final }, | ||
3435 | { NULL, NULL }, | ||
3436 | }; | ||
3437 | |||
3438 | static const luaL_Reg md_metatable[] = { | ||
3439 | { "__gc", &md__gc }, | ||
3440 | { NULL, NULL }, | ||
3441 | }; | ||
3442 | |||
3443 | static const luaL_Reg md_globals[] = { | ||
3444 | { "new", &md_new }, | ||
3445 | { "interpose", &md_interpose }, | ||
3446 | { NULL, NULL }, | ||
3447 | }; | ||
3448 | |||
3449 | int luaopen__openssl_digest(lua_State *L) { | ||
3450 | initall(L); | ||
3451 | |||
3452 | luaL_newlib(L, md_globals); | ||
3453 | |||
3454 | return 1; | ||
3455 | } /* luaopen__openssl_digest() */ | ||
3456 | |||
3457 | |||
3458 | /* | ||
3459 | * HMAC - openssl.hmac | ||
3460 | * | ||
3461 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
3462 | |||
3463 | static int hmac_new(lua_State *L) { | ||
3464 | const void *key; | ||
3465 | size_t len; | ||
3466 | const EVP_MD *type; | ||
3467 | HMAC_CTX *ctx; | ||
3468 | |||
3469 | key = luaL_checklstring(L, 1, &len); | ||
3470 | type = md_optdigest(L, 2); | ||
3471 | |||
3472 | ctx = prepudata(L, sizeof *ctx, HMAC_CLASS, NULL); | ||
3473 | |||
3474 | HMAC_Init_ex(ctx, key, len, type, NULL); | ||
3475 | |||
3476 | return 1; | ||
3477 | } /* hmac_new() */ | ||
3478 | |||
3479 | |||
3480 | static int hmac_interpose(lua_State *L) { | ||
3481 | return interpose(L, HMAC_CLASS); | ||
3482 | } /* hmac_interpose() */ | ||
3483 | |||
3484 | |||
3485 | static void hmac_update_(lua_State *L, HMAC_CTX *ctx, int from, int to) { | ||
3486 | int i; | ||
3487 | |||
3488 | for (i = from; i <= to; i++) { | ||
3489 | const void *p; | ||
3490 | size_t n; | ||
3491 | |||
3492 | p = luaL_checklstring(L, i, &n); | ||
3493 | |||
3494 | HMAC_Update(ctx, p, n); | ||
3495 | } | ||
3496 | } /* hmac_update_() */ | ||
3497 | |||
3498 | |||
3499 | static int hmac_update(lua_State *L) { | ||
3500 | HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS); | ||
3501 | |||
3502 | hmac_update_(L, ctx, 2, lua_gettop(L)); | ||
3503 | |||
3504 | lua_pushboolean(L, 1); | ||
3505 | |||
3506 | return 1; | ||
3507 | } /* hmac_update() */ | ||
3508 | |||
3509 | |||
3510 | static int hmac_final(lua_State *L) { | ||
3511 | HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS); | ||
3512 | unsigned char hmac[EVP_MAX_MD_SIZE]; | ||
3513 | unsigned len; | ||
3514 | |||
3515 | hmac_update_(L, ctx, 2, lua_gettop(L)); | ||
3516 | |||
3517 | HMAC_Final(ctx, hmac, &len); | ||
3518 | |||
3519 | lua_pushlstring(L, (char *)hmac, len); | ||
3520 | |||
3521 | return 1; | ||
3522 | } /* hmac_final() */ | ||
3523 | |||
3524 | |||
3525 | static int hmac__gc(lua_State *L) { | ||
3526 | HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS); | ||
3527 | |||
3528 | HMAC_CTX_cleanup(ctx); | ||
3529 | |||
3530 | return 0; | ||
3531 | } /* hmac__gc() */ | ||
3532 | |||
3533 | |||
3534 | static const luaL_Reg hmac_methods[] = { | ||
3535 | { "update", &hmac_update }, | ||
3536 | { "final", &hmac_final }, | ||
3537 | { NULL, NULL }, | ||
3538 | }; | ||
3539 | |||
3540 | static const luaL_Reg hmac_metatable[] = { | ||
3541 | { "__gc", &hmac__gc }, | ||
3542 | { NULL, NULL }, | ||
3543 | }; | ||
3544 | |||
3545 | static const luaL_Reg hmac_globals[] = { | ||
3546 | { "new", &hmac_new }, | ||
3547 | { "interpose", &hmac_interpose }, | ||
3548 | { NULL, NULL }, | ||
3549 | }; | ||
3550 | |||
3551 | int luaopen__openssl_hmac(lua_State *L) { | ||
3552 | initall(L); | ||
3553 | |||
3554 | luaL_newlib(L, hmac_globals); | ||
3555 | |||
3556 | return 1; | ||
3557 | } /* luaopen__openssl_hmac() */ | ||
3558 | |||
3559 | |||
3560 | /* | ||
3561 | * Cipher - openssl.cipher | ||
3562 | * | ||
3563 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
3564 | |||
3565 | static const EVP_CIPHER *cipher_checktype(lua_State *L, int index) { | ||
3566 | const char *name = luaL_checkstring(L, index); | ||
3567 | const EVP_CIPHER *type; | ||
3568 | |||
3569 | if (!(type = EVP_get_cipherbyname(name))) | ||
3570 | luaL_argerror(L, index, lua_pushfstring(L, "%s: invalid cipher type", name)); | ||
3571 | |||
3572 | return type; | ||
3573 | } /* cipher_checktype() */ | ||
3574 | |||
3575 | |||
3576 | static int cipher_new(lua_State *L) { | ||
3577 | const EVP_CIPHER *type; | ||
3578 | EVP_CIPHER_CTX *ctx; | ||
3579 | |||
3580 | type = cipher_checktype(L, 1); | ||
3581 | |||
3582 | ctx = prepudata(L, sizeof *ctx, CIPHER_CLASS, NULL); | ||
3583 | EVP_CIPHER_CTX_init(ctx); | ||
3584 | |||
3585 | if (!EVP_CipherInit_ex(ctx, type, NULL, NULL, NULL, -1)) | ||
3586 | return throwssl(L, "cipher.new"); | ||
3587 | |||
3588 | return 1; | ||
3589 | } /* cipher_new() */ | ||
3590 | |||
3591 | |||
3592 | static int cipher_interpose(lua_State *L) { | ||
3593 | return interpose(L, HMAC_CLASS); | ||
3594 | } /* cipher_interpose() */ | ||
3595 | |||
3596 | |||
3597 | static int cipher_init(lua_State *L, _Bool encrypt) { | ||
3598 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
3599 | const void *key, *iv; | ||
3600 | size_t n, m; | ||
3601 | |||
3602 | key = luaL_checklstring(L, 2, &n); | ||
3603 | m = (size_t)EVP_CIPHER_CTX_key_length(ctx); | ||
3604 | luaL_argcheck(L, n == m, 2, lua_pushfstring(L, "%d: invalid key length (should be %d)", (int)n, (int)m)); | ||
3605 | |||
3606 | iv = luaL_optlstring(L, 3, NULL, &n); | ||
3607 | m = (size_t)EVP_CIPHER_CTX_iv_length(ctx); | ||
3608 | luaL_argcheck(L, n == m, 3, lua_pushfstring(L, "%d: invalid IV length (should be %d)", (int)n, (int)m)); | ||
3609 | |||
3610 | if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, encrypt)) | ||
3611 | goto sslerr; | ||
3612 | |||
3613 | if (!lua_isnoneornil(L, 4)) { | ||
3614 | luaL_checktype(L, 4, LUA_TBOOLEAN); | ||
3615 | |||
3616 | if (!EVP_CIPHER_CTX_set_padding(ctx, lua_toboolean(L, 4))) | ||
3617 | goto sslerr; | ||
3618 | } | ||
3619 | |||
3620 | lua_settop(L, 1); | ||
3621 | |||
3622 | return 1; | ||
3623 | sslerr: | ||
3624 | return throwssl(L, (encrypt)? "cipher:encrypt" : "cipher:decrypt"); | ||
3625 | } /* cipher_init() */ | ||
3626 | |||
3627 | |||
3628 | static int cipher_encrypt(lua_State *L) { | ||
3629 | return cipher_init(L, 1); | ||
3630 | } /* cipher_encrypt() */ | ||
3631 | |||
3632 | |||
3633 | static int cipher_decrypt(lua_State *L) { | ||
3634 | return cipher_init(L, 0); | ||
3635 | } /* cipher_decrypt() */ | ||
3636 | |||
3637 | |||
3638 | static _Bool cipher_update_(lua_State *L, EVP_CIPHER_CTX *ctx, luaL_Buffer *B, int from, int to) { | ||
3639 | const unsigned char *p, *pe; | ||
3640 | size_t block, step, n; | ||
3641 | int i; | ||
3642 | |||
3643 | block = EVP_CIPHER_CTX_block_size(ctx); | ||
3644 | |||
3645 | if (LUAL_BUFFERSIZE < block * 2) | ||
3646 | luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%d) < 2 * EVP_CIPHER_CTX_block_size(%d)", (int)LUAL_BUFFERSIZE, (int)block); | ||
3647 | |||
3648 | step = LUAL_BUFFERSIZE - block; | ||
3649 | |||
3650 | for (i = from; i <= to; i++) { | ||
3651 | p = (const unsigned char *)luaL_checklstring(L, i, &n); | ||
3652 | pe = p + n; | ||
3653 | |||
3654 | while (p < pe) { | ||
3655 | int in = (int)MIN((size_t)(pe - p), step), out; | ||
3656 | |||
3657 | if (!EVP_CipherUpdate(ctx, (void *)luaL_prepbuffer(B), &out, p, in)) | ||
3658 | return 0; | ||
3659 | |||
3660 | p += in; | ||
3661 | luaL_addsize(B, out); | ||
3662 | } | ||
3663 | } | ||
3664 | |||
3665 | return 1; | ||
3666 | } /* cipher_update_() */ | ||
3667 | |||
3668 | |||
3669 | static int cipher_update(lua_State *L) { | ||
3670 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
3671 | luaL_Buffer B; | ||
3672 | |||
3673 | luaL_buffinit(L, &B); | ||
3674 | |||
3675 | if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L))) | ||
3676 | goto sslerr; | ||
3677 | |||
3678 | luaL_pushresult(&B); | ||
3679 | |||
3680 | return 1; | ||
3681 | sslerr: | ||
3682 | lua_pushnil(L); | ||
3683 | pusherror(L, NULL); | ||
3684 | |||
3685 | return 2; | ||
3686 | } /* cipher_update() */ | ||
3687 | |||
3688 | |||
3689 | static int cipher_final(lua_State *L) { | ||
3690 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
3691 | luaL_Buffer B; | ||
3692 | size_t block; | ||
3693 | int out; | ||
3694 | |||
3695 | luaL_buffinit(L, &B); | ||
3696 | |||
3697 | if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L))) | ||
3698 | goto sslerr; | ||
3699 | |||
3700 | block = EVP_CIPHER_CTX_block_size(ctx); | ||
3701 | |||
3702 | if (LUAL_BUFFERSIZE < block) | ||
3703 | return luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%d) < EVP_CIPHER_CTX_block_size(%d)", (int)LUAL_BUFFERSIZE, (int)block); | ||
3704 | |||
3705 | if (!EVP_CipherFinal(ctx, (void *)luaL_prepbuffer(&B), &out)) | ||
3706 | goto sslerr; | ||
3707 | |||
3708 | luaL_addsize(&B, out); | ||
3709 | luaL_pushresult(&B); | ||
3710 | |||
3711 | return 1; | ||
3712 | sslerr: | ||
3713 | lua_pushnil(L); | ||
3714 | pusherror(L, NULL); | ||
3715 | |||
3716 | return 2; | ||
3717 | } /* cipher_final() */ | ||
3718 | |||
3719 | |||
3720 | static int cipher__gc(lua_State *L) { | ||
3721 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
3722 | |||
3723 | EVP_CIPHER_CTX_cleanup(ctx); | ||
3724 | |||
3725 | return 0; | ||
3726 | } /* cipher__gc() */ | ||
3727 | |||
3728 | |||
3729 | static const luaL_Reg cipher_methods[] = { | ||
3730 | { "encrypt", &cipher_encrypt }, | ||
3731 | { "decrypt", &cipher_decrypt }, | ||
3732 | { "update", &cipher_update }, | ||
3733 | { "final", &cipher_final }, | ||
3734 | { NULL, NULL }, | ||
3735 | }; | ||
3736 | |||
3737 | static const luaL_Reg cipher_metatable[] = { | ||
3738 | { "__gc", &cipher__gc }, | ||
3739 | { NULL, NULL }, | ||
3740 | }; | ||
3741 | |||
3742 | static const luaL_Reg cipher_globals[] = { | ||
3743 | { "new", &cipher_new }, | ||
3744 | { "interpose", &cipher_interpose }, | ||
3745 | { NULL, NULL }, | ||
3746 | }; | ||
3747 | |||
3748 | int luaopen__openssl_cipher(lua_State *L) { | ||
3749 | initall(L); | ||
3750 | |||
3751 | luaL_newlib(L, cipher_globals); | ||
3752 | |||
3753 | return 1; | ||
3754 | } /* luaopen__openssl_cipher() */ | ||
3755 | |||
3756 | |||
3757 | /* | ||
3758 | * Rand - openssl.rand | ||
3759 | * | ||
3760 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
3761 | |||
3762 | static int rand_bytes(lua_State *L) { | ||
3763 | int size = luaL_checkint(L, 1); | ||
3764 | luaL_Buffer B; | ||
3765 | int count = 0, n; | ||
3766 | |||
3767 | luaL_buffinit(L, &B); | ||
3768 | |||
3769 | while (count < size) { | ||
3770 | n = MIN((size - count), LUAL_BUFFERSIZE); | ||
3771 | |||
3772 | if (!RAND_bytes((void *)luaL_prepbuffer(&B), n)) | ||
3773 | return throwssl(L, "rand.bytes"); | ||
3774 | |||
3775 | luaL_addsize(&B, n); | ||
3776 | count += n; | ||
3777 | } | ||
3778 | |||
3779 | luaL_pushresult(&B); | ||
3780 | |||
3781 | return 1; | ||
3782 | } /* rand_bytes() */ | ||
3783 | |||
3784 | |||
3785 | static int rand_ready(lua_State *L) { | ||
3786 | lua_pushboolean(L, RAND_status() == 1); | ||
3787 | |||
3788 | return 1; | ||
3789 | } /* rand_ready() */ | ||
3790 | |||
3791 | |||
3792 | static unsigned long long rand_llu(lua_State *L) { | ||
3793 | unsigned long long llu; | ||
3794 | |||
3795 | if (!RAND_bytes((void *)&llu, sizeof llu)) | ||
3796 | throwssl(L, "rand.uniform"); | ||
3797 | |||
3798 | return llu; | ||
3799 | } /* rand_llu() */ | ||
3800 | |||
3801 | /* | ||
3802 | * The following algorithm for rand_uniform() is taken from OpenBSD's | ||
3803 | * arc4random_uniform, written by Otto Moerbeek, with subsequent | ||
3804 | * simplification by Jorden Verwer. Otto's source code comment reads | ||
3805 | * | ||
3806 | * Uniformity is achieved by generating new random numbers until the one | ||
3807 | * returned is outside the range [0, 2**32 % upper_bound). This guarantees | ||
3808 | * the selected random number will be inside [2**32 % upper_bound, 2**32) | ||
3809 | * which maps back to [0, upper_bound) after reduction modulo upper_bound. | ||
3810 | * | ||
3811 | * -- | ||
3812 | * A more bit-efficient approach by the eminent statistician Herman Rubin | ||
3813 | * can be found in this sci.crypt Usenet post. | ||
3814 | * | ||
3815 | * From: hrubin@odds.stat.purdue.edu (Herman Rubin) | ||
3816 | * Newsgroups: sci.crypt | ||
3817 | * Subject: Re: Generating a random number between 0 and N-1 | ||
3818 | * Date: 14 Nov 2002 11:20:37 -0500 | ||
3819 | * Organization: Purdue University Statistics Department | ||
3820 | * Lines: 40 | ||
3821 | * Message-ID: <ar0igl$1ak2@odds.stat.purdue.edu> | ||
3822 | * References: <yO%y9.19646$RO1.373975@weber.videotron.net> <3DCD8D75.40408@nospam.com> | ||
3823 | * NNTP-Posting-Host: odds.stat.purdue.edu | ||
3824 | * X-Trace: mozo.cc.purdue.edu 1037290837 9316 128.210.141.13 (14 Nov 2002 16:20:37 GMT) | ||
3825 | * X-Complaints-To: ne...@news.purdue.edu | ||
3826 | * NNTP-Posting-Date: Thu, 14 Nov 2002 16:20:37 +0000 (UTC) | ||
3827 | * Xref: archiver1.google.com sci.crypt:78935 | ||
3828 | * | ||
3829 | * In article <3DCD8D7...@nospam.com>, | ||
3830 | * Michael Amling <nos...@nospam.com> wrote: | ||
3831 | * >Carlos Moreno wrote: | ||
3832 | * | ||
3833 | * I have already posted on this, but a repeat might be | ||
3834 | * in order. | ||
3835 | * | ||
3836 | * If one can trust random bits, the most bitwise efficient | ||
3837 | * manner to get a single random integer between 0 and N-1 | ||
3838 | * can be obtained as follows; the code can be made more | ||
3839 | * computationally efficient. I believe it is easier to | ||
3840 | * understand with gotos. I am assuming N>1. | ||
3841 | * | ||
3842 | * i = 0; j = 1; | ||
3843 | * | ||
3844 | * loop: j=2*j; i=2*i+RANBIT; | ||
3845 | * if (j < N) goto loop; | ||
3846 | * if (i >= N) { | ||
3847 | * i = i - N; | ||
3848 | * j = j - N; | ||
3849 | * goto loop:} | ||
3850 | * else return (i); | ||
3851 | * | ||
3852 | * The algorithm works because at each stage i is uniform | ||
3853 | * between 0 and j-1. | ||
3854 | * | ||
3855 | * Another possibility is to generate k bits, where 2^k >= N. | ||
3856 | * If 2^k = c*N + remainder, generate the appropriate value | ||
3857 | * if a k-bit random number is less than c*N. | ||
3858 | * | ||
3859 | * For N = 17 (numbers just larger than powers of 2 are "bad"), | ||
3860 | * the amount of information is about 4.09 bits, the best | ||
3861 | * algorithm to generate one random number takes about 5.765 | ||
3862 | * bits, taking k = 5 uses 9.412 bits, taking k = 6 or 7 uses | ||
3863 | * 7.529 bits. These are averages, but the tails are not bad. | ||
3864 | * | ||
3865 | * (https://groups.google.com/forum/message/raw?msg=sci.crypt/DMslf6tSrD8/rv9rk6oP3r4J) | ||
3866 | */ | ||
3867 | static int rand_uniform(lua_State *L) { | ||
3868 | if (lua_isnoneornil(L, 1)) { | ||
3869 | unsigned long long r = rand_llu(L); | ||
3870 | |||
3871 | lua_pushnumber(L, r); | ||
3872 | |||
3873 | return 1; | ||
3874 | } else { | ||
3875 | unsigned long long N = luaL_checknumber(L, 1); | ||
3876 | unsigned long long r, m; | ||
3877 | |||
3878 | luaL_argcheck(L, N > 1, 1, lua_pushfstring(L, "[0, %d): interval is empty", (int)N)); | ||
3879 | |||
3880 | m = -N % N; | ||
3881 | |||
3882 | do { | ||
3883 | r = rand_llu(L); | ||
3884 | } while (r < m); | ||
3885 | |||
3886 | lua_pushnumber(L, (r % N)); | ||
3887 | |||
3888 | return 1; | ||
3889 | } | ||
3890 | } /* rand_uniform() */ | ||
3891 | |||
3892 | |||
3893 | static const luaL_Reg rand_globals[] = { | ||
3894 | { "bytes", &rand_bytes }, | ||
3895 | { "ready", &rand_ready }, | ||
3896 | { "uniform", &rand_uniform }, | ||
3897 | { NULL, NULL }, | ||
3898 | }; | ||
3899 | |||
3900 | int luaopen__openssl_rand(lua_State *L) { | ||
3901 | initall(L); | ||
3902 | |||
3903 | luaL_newlib(L, rand_globals); | ||
3904 | |||
3905 | return 1; | ||
3906 | } /* luaopen__openssl_rand() */ | ||
3907 | |||
3908 | |||
3909 | static void initall(lua_State *L) { | ||
3910 | ERR_load_crypto_strings(); | ||
3911 | OpenSSL_add_all_algorithms(); | ||
3912 | |||
3913 | addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable); | ||
3914 | addclass(L, PUBKEY_CLASS, pk_methods, pk_metatable); | ||
3915 | addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable); | ||
3916 | addclass(L, X509_GENS_CLASS, gn_methods, gn_metatable); | ||
3917 | addclass(L, X509_CERT_CLASS, xc_methods, xc_metatable); | ||
3918 | addclass(L, X509_CSR_CLASS, xr_methods, xr_metatable); | ||
3919 | addclass(L, X509_CHAIN_CLASS, xl_methods, xl_metatable); | ||
3920 | addclass(L, X509_STORE_CLASS, xs_methods, xs_metatable); | ||
3921 | addclass(L, SSL_CTX_CLASS, sx_methods, sx_metatable); | ||
3922 | addclass(L, SSL_CLASS, ssl_methods, ssl_metatable); | ||
3923 | addclass(L, DIGEST_CLASS, md_methods, md_metatable); | ||
3924 | addclass(L, HMAC_CLASS, hmac_methods, hmac_metatable); | ||
3925 | addclass(L, CIPHER_CLASS, cipher_methods, cipher_metatable); | ||
3926 | } /* initall() */ | ||
3927 | |||
3928 | |||
3929 | #endif /* L_OPENSSL_H */ | ||
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.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.pubkey.lua b/src/openssl.pubkey.lua new file mode 100644 index 0000000..6dc5614 --- /dev/null +++ b/src/openssl.pubkey.lua | |||
@@ -0,0 +1,4 @@ | |||
1 | local pubkey = require"_openssl.pubkey" | ||
2 | |||
3 | return pubkey | ||
4 | |||
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..44a9163 --- /dev/null +++ b/src/openssl.ssl.context.lua | |||
@@ -0,0 +1,3 @@ | |||
1 | local ctx = require"_openssl.ssl.context" | ||
2 | |||
3 | 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..66f16e7 --- /dev/null +++ b/src/openssl.x509.altname.lua | |||
@@ -0,0 +1,13 @@ | |||
1 | local altname = require"_openssl.x509.altname" | ||
2 | |||
3 | altname.interpose("__tostring", function (self) | ||
4 | local t = { } | ||
5 | |||
6 | for k, v in pairs(self) do | ||
7 | t[#t + 1] = k .. ":" .. v | ||
8 | end | ||
9 | |||
10 | return table.concat(t, ", ") | ||
11 | end) | ||
12 | |||
13 | 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.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..a531502 --- /dev/null +++ b/src/openssl.x509.name.lua | |||
@@ -0,0 +1,13 @@ | |||
1 | local name = require"_openssl.x509.name" | ||
2 | |||
3 | name.interpose("__tostring", function (self) | ||
4 | local t = { } | ||
5 | |||
6 | for k, v in pairs(self) do | ||
7 | t[#t + 1] = k .. "=" .. v | ||
8 | end | ||
9 | |||
10 | return table.concat(t, ", ") | ||
11 | end) | ||
12 | |||
13 | 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 | ||