aboutsummaryrefslogtreecommitdiff
path: root/vendor/luasec
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/luasec')
-rw-r--r--vendor/luasec/.gitignore3
-rw-r--r--vendor/luasec/CHANGELOG257
-rw-r--r--vendor/luasec/INSTALL39
-rw-r--r--vendor/luasec/LICENSE21
-rw-r--r--vendor/luasec/README.md6
-rw-r--r--vendor/luasec/luasec-1.3.2-1.rockspec105
-rw-r--r--vendor/luasec/src/Makefile66
-rw-r--r--vendor/luasec/src/compat.h63
-rw-r--r--vendor/luasec/src/config.c108
-rw-r--r--vendor/luasec/src/context.c1099
-rw-r--r--vendor/luasec/src/context.h47
-rw-r--r--vendor/luasec/src/ec.c116
-rw-r--r--vendor/luasec/src/ec.h22
-rw-r--r--vendor/luasec/src/https.lua147
-rw-r--r--vendor/luasec/src/luasocket/LICENSE21
-rw-r--r--vendor/luasec/src/luasocket/Makefile26
-rw-r--r--vendor/luasec/src/luasocket/buffer.c278
-rw-r--r--vendor/luasec/src/luasocket/buffer.h45
-rw-r--r--vendor/luasec/src/luasocket/io.c30
-rw-r--r--vendor/luasec/src/luasocket/io.h65
-rw-r--r--vendor/luasec/src/luasocket/socket.h78
-rw-r--r--vendor/luasec/src/luasocket/timeout.c220
-rw-r--r--vendor/luasec/src/luasocket/timeout.h28
-rw-r--r--vendor/luasec/src/luasocket/usocket.c441
-rw-r--r--vendor/luasec/src/luasocket/usocket.h70
-rw-r--r--vendor/luasec/src/luasocket/wsocket.c429
-rw-r--r--vendor/luasec/src/luasocket/wsocket.h38
-rw-r--r--vendor/luasec/src/options.c185
-rw-r--r--vendor/luasec/src/options.h22
-rw-r--r--vendor/luasec/src/options.lua93
-rw-r--r--vendor/luasec/src/ssl.c1092
-rw-r--r--vendor/luasec/src/ssl.h41
-rw-r--r--vendor/luasec/src/ssl.lua313
-rw-r--r--vendor/luasec/src/x509.c750
-rw-r--r--vendor/luasec/src/x509.h31
35 files changed, 6395 insertions, 0 deletions
diff --git a/vendor/luasec/.gitignore b/vendor/luasec/.gitignore
new file mode 100644
index 00000000..355518b2
--- /dev/null
+++ b/vendor/luasec/.gitignore
@@ -0,0 +1,3 @@
1/src/*.o
2/src/luasocket/*.o
3/*.dll
diff --git a/vendor/luasec/CHANGELOG b/vendor/luasec/CHANGELOG
new file mode 100644
index 00000000..f7c0a780
--- /dev/null
+++ b/vendor/luasec/CHANGELOG
@@ -0,0 +1,257 @@
1--------------------------------------------------------------------------------
2LuaSec 1.3.2
3---------------
4This version includes:
5
6* Fix: place EAI_OVERFLOW inside macro, unbreak build on <10.7 (Sergey Fedorov)
7* Fix: Expand workaround for zero errno to OpenSSL 3.0.x (Kim Alvefur)
8* Fix: reset block timeout at send or receive (MartinDahlberg)
9
10--------------------------------------------------------------------------------
11LuaSec 1.3.1
12---------------
13This version includes:
14
15* Fix: check if PSK is available
16
17--------------------------------------------------------------------------------
18LuaSec 1.3.0
19---------------
20This version includes:
21
22* Add :getlocalchain() + :getlocalcertificate() to mirror the peer methods (@mwild1)
23* Add Pre-Shared Key (PSK) support (@jclab-joseph)
24
25--------------------------------------------------------------------------------
26LuaSec 1.2.0
27---------------
28This version includes:
29
30* Add key material export method
31* Backguard compat for openssl on providers, like LTS linuxes
32
33--------------------------------------------------------------------------------
34LuaSec 1.1.0
35---------------
36This version includes:
37
38* Fix missing DANE flag
39* Remove unused parameter in https.lua
40
41--------------------------------------------------------------------------------
42LuaSec 1.0.2
43---------------
44This version includes:
45
46* Fix handle SSL_send SYSCALL error without errno
47* Fix off by one in cert:validat(notafter)
48* Fix meth_get_{sinagure => signature}_name function name
49* Fix update the Lua state reference on the selected SSL context after SNI
50* Fix ignore SSL_OP_BIT(n) macro and update option.c
51
52--------------------------------------------------------------------------------
53LuaSec 1.0.1
54---------------
55This version includes:
56
57
58* Fix luaL_buffinit() can use the stack and broke buffer_meth_receive()
59
60--------------------------------------------------------------------------------
61LuaSec 1.0
62---------------
63This version includes:
64
65
66* Add cert:getsignaturename()
67
68--------------------------------------------------------------------------------
69LuaSec 0.9
70---------------
71This version includes:
72
73
74* Add DNS-based Authentication of Named Entities (DANE) support
75* Add __close() metamethod
76* Fix deprecation warnings with OpenSSL 1.1
77* Fix special case listing of TLS 1.3 EC curves
78* Fix general_name leak in cert:extensions()
79* Fix unexported 'ssl.config' table
80* Replace $(LD) with $(CCLD) variable
81* Remove multiple definitions of 'ssl_options' variable
82* Use tag in git format: v0.9
83
84--------------------------------------------------------------------------------
85LuaSec 0.8.2
86---------------
87This version includes:
88
89* Fix unexported 'ssl.config' table (backported)
90
91--------------------------------------------------------------------------------
92LuaSec 0.8.1
93---------------
94This version includes:
95
96* Fix general_name leak in cert:extensions() (backported)
97
98--------------------------------------------------------------------------------
99LuaSec 0.8
100---------------
101This version includes:
102
103* Add support to ALPN
104* Add support to TLS 1.3
105* Add support to multiple certificates
106* Add timeout to https module (https.TIMEOUT)
107* Drop support to SSL 3.0
108* Drop support to TLS 1.0 from https module
109* Fix invalid reference to Lua state
110* Fix memory leak when get certficate extensions
111
112--------------------------------------------------------------------------------
113LuaSec 0.7.2
114---------------
115This version includes:
116
117* Fix unexported 'ssl.config' table (backported)
118
119--------------------------------------------------------------------------------
120LuaSec 0.7.1
121---------------
122This version includes:
123
124* Fix general_name leak in cert:extensions() (backported)
125
126--------------------------------------------------------------------------------
127LuaSec 0.7
128---------------
129LuaSec depends on OpenSSL, and integrates with LuaSocket to make it
130easy to add secure connections to any Lua applications or scripts.
131
132Documentation: https://github.com/brunoos/luasec/wiki
133
134This version includes:
135
136* Add support to OpenSSL 1.1.0
137* Add support to elliptic curves list
138* Add ssl.config that exports some OpenSSL information
139* Add integration with luaossl
140
141--------------------------------------------------------------------------------
142LuaSec 0.6
143------------
144LuaSec depends on OpenSSL, and integrates with LuaSocket to make it
145easy to add secure connections to any Lua applications or scripts.
146
147Documentation: https://github.com/brunoos/luasec/wiki
148
149This version includes:
150
151* Lua 5.2 and 5.3 compatibility
152
153* Context module:
154 - Add ctx:checkkey()
155
156* SSL module:
157 - Add conn:sni() and conn:getsniname()
158
159* Context options:
160 - Add "any" protocol ("sslv23" is deprecated)
161
162* HTTPS module:
163 - Using "any" protocol without SSLv2/SSLv3, by default
164
165* X509 module:
166 - Human readable IP address
167 - Add cert:issued()
168 - Add cert:pubkey()
169
170* Some bug fixes
171
172
173=> Thanks to everyone who collaborate with LuaSec <=
174
175--------------------------------------------------------------------------------
176LuaSec 0.5
177------------
178LuaSec depends on OpenSSL, and integrates with LuaSocket to make it
179easy to add secure connections to any Lua applications or scripts.
180
181This version includes:
182
183 * A new certificate (X509) API, which supports:
184 - Reading the subject (identity) and issuer of the certificate.
185 - Reading various X509 extensions, including email and dnsName.
186 - Converting certificates to and from the standard ASCII PEM
187 format.
188 - Generating the fingerprint/digest of a certificate (using SHA1,
189 SHA256 or SHA512).
190 - Reading the certificate's expiration, serial number, and other
191 info.
192
193 * The ability to get more detailed information from OpenSSL about
194 why a certificate failed verification, for each certificate in the
195 chain.
196
197 * Flags to force acceptance of invalid certificates, e.g. to allow
198 the use of self-signed certificates in a Trust On First Use model.
199
200 * Flags to control checking CRLs for certificate revocation status.
201
202 * Support for ECDH cipher suites.
203
204 * An API to get the TLS 'finished' messages used for SASL channel
205 binding (e.g. the SCRAM PLUS mechanisms).
206
207The work in this release was undertaken by Kim Alvefur, Paul Aurich,
208Tobias Markmann, Bruno Silvestre and Matthew Wild.
209
210--------------------------------------------------------------------------------
211LuaSec 0.4.1
212------------
213- SSL options updated --- based on OpenSSL 1.0.0d.
214- Activate SSL_MODE_RELEASE_BUFFERS by default if it is available.
215 (thanks Prosody project)
216
217---------------------------------------------------------------------------------
218LuaSec 0.4
219------------
220- Add option 'no_ticket' (included in OpenSSL 0.9.8f).
221- Add HTTPS module. (thanks Tomas Guisasola and Pablo Musa)
222
223--------------------------------------------------------------------------------
224LuaSec 0.3.3
225------------
226- BUG: Clear the error queue before call I/O functions (see SSL_get_error
227 manual).
228 (thanks Matthew Wild)
229
230--------------------------------------------------------------------------------
231LuaSec 0.3.2
232------------
233- BUG: Windows uses a different way to report socket error.
234 (thanks Sebastien Perin)
235
236--------------------------------------------------------------------------------
237LuaSec 0.3.1
238------------
239- BUG: receive("a") returns 'closed' error instead of the content when the
240 SSL/TLS connection is shut down cleanly. (thanks Matthias Diener)
241
242--------------------------------------------------------------------------------
243LuaSec 0.3
244----------
245- Add functions ssl.rawcontext() and ssl.rawconnection()
246- Add support to encrypted key password. (thanks Norbert Kiesel)
247
248--------------------------------------------------------------------------------
249LuaSec 0.2.1
250------------
251- 'key' and 'certificate' configurations become optional. (thanks René Rebe)
252- Add '_VERSION' variable to module.
253
254--------------------------------------------------------------------------------
255LuaSec 0.2
256----------
257Initial version
diff --git a/vendor/luasec/INSTALL b/vendor/luasec/INSTALL
new file mode 100644
index 00000000..07b94df8
--- /dev/null
+++ b/vendor/luasec/INSTALL
@@ -0,0 +1,39 @@
1LuaSec 1.3.2
2------------
3
4* OpenSSL options:
5
6 By default, this version includes options for OpenSSL 3.0.8
7
8 If you need to generate the options for a different version of OpenSSL:
9
10 $ cd src
11 $ lua options.lua -g /usr/include/openssl/ssl.h > options.c
12
13--------------------------------------------------------------------------------
14
15* On Linux, BSD, and Mac OS X:
16
17 - Edit 'Makefile'
18 * Inform the path to where install the Lua modules (LUAPATH) and binaries
19 modules (LUACPATH)
20 * If Lua or OpenSSL are not in the default path, set the
21 variables INCDIR and LIBDIR.
22 * For Mac OS X, set the variable MACOSX_VERSION.
23
24 - Use 'make <platform>' to compile
25 * Platforms: linux, bsd, or macosx
26
27 - Use 'make install' to install the modules.
28
29--------------------------------------------------------------------------------
30
31* On Windows:
32
33 - Use the Visual C++ project to compile the library.
34
35 - Copy the 'ssl.lua' file to some place in your LUA_PATH.
36
37 - Copy the 'ssl.dll' file to some place in your LUA_CPATH.
38
39 - Create a directory 'ssl' in your LUA_PATH and copy 'https.lua' to it.
diff --git a/vendor/luasec/LICENSE b/vendor/luasec/LICENSE
new file mode 100644
index 00000000..09df9964
--- /dev/null
+++ b/vendor/luasec/LICENSE
@@ -0,0 +1,21 @@
1LuaSec 1.3.2 license
2Copyright (C) 2006-2023 Bruno Silvestre, UFG
3
4Permission is hereby granted, free of charge, to any person obtaining
5a copy of this software and associated documentation files (the
6"Software"), to deal in the Software without restriction, including
7without limitation the rights to use, copy, modify, merge, publish,
8distribute, sublicense, and/or sell copies of the Software, and to
9permit persons to whom the Software is furnished to do so, subject to
10the following conditions:
11
12The above copyright notice and this permission notice shall be
13included in all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/luasec/README.md b/vendor/luasec/README.md
new file mode 100644
index 00000000..afdce4ee
--- /dev/null
+++ b/vendor/luasec/README.md
@@ -0,0 +1,6 @@
1LuaSec 1.3.2
2===============
3LuaSec depends on OpenSSL, and integrates with LuaSocket to make it
4easy to add secure connections to any Lua applications or scripts.
5
6Documentation: https://github.com/brunoos/luasec/wiki
diff --git a/vendor/luasec/luasec-1.3.2-1.rockspec b/vendor/luasec/luasec-1.3.2-1.rockspec
new file mode 100644
index 00000000..a6a36d78
--- /dev/null
+++ b/vendor/luasec/luasec-1.3.2-1.rockspec
@@ -0,0 +1,105 @@
1package = "LuaSec"
2version = "1.3.2-1"
3source = {
4 url = "git+https://github.com/brunoos/luasec",
5 tag = "v1.3.2",
6}
7description = {
8 summary = "A binding for OpenSSL library to provide TLS/SSL communication over LuaSocket.",
9 detailed = "This version delegates to LuaSocket the TCP connection establishment between the client and server. Then LuaSec uses this connection to start a secure TLS/SSL session.",
10 homepage = "https://github.com/brunoos/luasec/wiki",
11 license = "MIT"
12}
13dependencies = {
14 "lua >= 5.1", "luasocket"
15}
16external_dependencies = {
17 platforms = {
18 unix = {
19 OPENSSL = {
20 header = "openssl/ssl.h",
21 library = "ssl"
22 }
23 },
24 windows = {
25 OPENSSL = {
26 header = "openssl/ssl.h",
27 }
28 },
29 }
30}
31build = {
32 type = "builtin",
33 copy_directories = {
34 "samples"
35 },
36 platforms = {
37 unix = {
38 install = {
39 lib = {
40 "ssl.so"
41 },
42 lua = {
43 "src/ssl.lua", ['ssl.https'] = "src/https.lua"
44 }
45 },
46 modules = {
47 ssl = {
48 defines = {
49 "WITH_LUASOCKET", "LUASOCKET_DEBUG",
50 },
51 incdirs = {
52 "$(OPENSSL_INCDIR)", "src/", "src/luasocket",
53 },
54 libdirs = {
55 "$(OPENSSL_LIBDIR)"
56 },
57 libraries = {
58 "ssl", "crypto"
59 },
60 sources = {
61 "src/options.c", "src/config.c", "src/ec.c",
62 "src/x509.c", "src/context.c", "src/ssl.c",
63 "src/luasocket/buffer.c", "src/luasocket/io.c",
64 "src/luasocket/timeout.c", "src/luasocket/usocket.c"
65 }
66 }
67 }
68 },
69 windows = {
70 install = {
71 lib = {
72 "ssl.dll"
73 },
74 lua = {
75 "src/ssl.lua", ['ssl.https'] = "src/https.lua"
76 }
77 },
78 modules = {
79 ssl = {
80 defines = {
81 "WIN32", "NDEBUG", "_WINDOWS", "_USRDLL", "LSEC_EXPORTS", "BUFFER_DEBUG", "LSEC_API=__declspec(dllexport)",
82 "WITH_LUASOCKET", "LUASOCKET_DEBUG",
83 "LUASEC_INET_NTOP", "WINVER=0x0501", "_WIN32_WINNT=0x0501", "NTDDI_VERSION=0x05010300"
84 },
85 libdirs = {
86 "$(OPENSSL_LIBDIR)",
87 "$(OPENSSL_BINDIR)",
88 },
89 libraries = {
90 "libssl", "libcrypto", "ws2_32"
91 },
92 incdirs = {
93 "$(OPENSSL_INCDIR)", "src/", "src/luasocket"
94 },
95 sources = {
96 "src/options.c", "src/config.c", "src/ec.c",
97 "src/x509.c", "src/context.c", "src/ssl.c",
98 "src/luasocket/buffer.c", "src/luasocket/io.c",
99 "src/luasocket/timeout.c", "src/luasocket/wsocket.c"
100 }
101 }
102 }
103 }
104 }
105}
diff --git a/vendor/luasec/src/Makefile b/vendor/luasec/src/Makefile
new file mode 100644
index 00000000..9b06a038
--- /dev/null
+++ b/vendor/luasec/src/Makefile
@@ -0,0 +1,66 @@
1CMOD=ssl.so
2LMOD=ssl.lua
3
4OBJS= \
5 options.o \
6 x509.o \
7 context.o \
8 ssl.o \
9 config.o \
10 ec.o
11
12LIBS=-lssl -lcrypto -lluasocket
13
14WARN=-Wall -pedantic
15
16BSD_CFLAGS=-O2 -fPIC $(WARN) $(INCDIR) $(DEFS)
17BSD_LDFLAGS=-O -fPIC -shared $(LIBDIR)
18
19LNX_CFLAGS=-O2 -fPIC $(WARN) $(INCDIR) $(DEFS)
20LNX_LDFLAGS=-O -fPIC -shared $(LIBDIR)
21
22MAC_ENV=env MACOSX_DEPLOYMENT_TARGET='$(MACVER)'
23MAC_CFLAGS=-O2 -fno-common $(WARN) $(INCDIR) $(DEFS)
24MAC_LDFLAGS=-bundle -undefined dynamic_lookup $(LIBDIR)
25
26INSTALL = install
27CC ?= cc
28CCLD ?= $(MYENV) $(CC)
29CFLAGS += $(MYCFLAGS)
30LDFLAGS += $(MYLDFLAGS)
31
32.PHONY: all clean install none linux bsd macosx luasocket
33
34all:
35
36install: $(CMOD) $(LMOD)
37 $(INSTALL) -d $(DESTDIR)$(LUAPATH)/ssl $(DESTDIR)$(LUACPATH)
38 $(INSTALL) $(CMOD) $(DESTDIR)$(LUACPATH)
39 $(INSTALL) -m644 $(LMOD) $(DESTDIR)$(LUAPATH)
40 $(INSTALL) -m644 https.lua $(DESTDIR)$(LUAPATH)/ssl
41
42linux:
43 @$(MAKE) $(CMOD) MYCFLAGS="$(LNX_CFLAGS)" MYLDFLAGS="$(LNX_LDFLAGS)" EXTRA="$(EXTRA)"
44
45bsd:
46 @$(MAKE) $(CMOD) MYCFLAGS="$(BSD_CFLAGS)" MYLDFLAGS="$(BSD_LDFLAGS)" EXTRA="$(EXTRA)"
47
48macosx:
49 @$(MAKE) $(CMOD) MYCFLAGS="$(MAC_CFLAGS)" MYLDFLAGS="$(MAC_LDFLAGS)" MYENV="$(MAC_ENV)" EXTRA="$(EXTRA)"
50
51luasocket:
52 @cd luasocket && $(MAKE)
53
54$(CMOD): $(EXTRA) $(OBJS)
55 $(CCLD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
56
57clean:
58 cd luasocket && $(MAKE) clean
59 rm -f $(OBJS) $(CMOD)
60
61options.o: options.h options.c
62ec.o: ec.c ec.h
63x509.o: x509.c x509.h compat.h
64context.o: context.c context.h ec.h compat.h options.h
65ssl.o: ssl.c ssl.h context.h x509.h compat.h
66config.o: config.c ec.h options.h compat.h
diff --git a/vendor/luasec/src/compat.h b/vendor/luasec/src/compat.h
new file mode 100644
index 00000000..9f97e2a6
--- /dev/null
+++ b/vendor/luasec/src/compat.h
@@ -0,0 +1,63 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2006-2023 Bruno Silvestre
5 *
6 *--------------------------------------------------------------------------*/
7
8#ifndef LSEC_COMPAT_H
9#define LSEC_COMPAT_H
10
11#include <openssl/ssl.h>
12
13//------------------------------------------------------------------------------
14
15#if defined(_WIN32)
16#define LSEC_API __declspec(dllexport)
17#else
18#define LSEC_API extern
19#endif
20
21//------------------------------------------------------------------------------
22
23#if (LUA_VERSION_NUM == 501)
24
25#define luaL_testudata(L, ud, tname) lsec_testudata(L, ud, tname)
26#define setfuncs(L, R) luaL_register(L, NULL, R)
27#define lua_rawlen(L, i) lua_objlen(L, i)
28
29#ifndef luaL_newlib
30#define luaL_newlib(L, R) do { lua_newtable(L); luaL_register(L, NULL, R); } while(0)
31#endif
32
33#else
34#define setfuncs(L, R) luaL_setfuncs(L, R, 0)
35#endif
36
37//------------------------------------------------------------------------------
38
39#if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x1010000fL))
40#define LSEC_ENABLE_DANE
41#endif
42
43//------------------------------------------------------------------------------
44
45#if !((defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x2070000fL)) || (OPENSSL_VERSION_NUMBER < 0x1010000fL))
46#define LSEC_API_OPENSSL_1_1_0
47#endif
48
49//------------------------------------------------------------------------------
50
51#if !defined(LIBRESSL_VERSION_NUMBER) && ((OPENSSL_VERSION_NUMBER & 0xFFFFF000L) == 0x10101000L || (OPENSSL_VERSION_NUMBER & 0xFFFFF000L) == 0x30000000L)
52#define LSEC_OPENSSL_ERRNO_BUG
53#endif
54
55//------------------------------------------------------------------------------
56
57#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_NO_PSK)
58#define LSEC_ENABLE_PSK
59#endif
60
61//------------------------------------------------------------------------------
62
63#endif
diff --git a/vendor/luasec/src/config.c b/vendor/luasec/src/config.c
new file mode 100644
index 00000000..5f0e2c60
--- /dev/null
+++ b/vendor/luasec/src/config.c
@@ -0,0 +1,108 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2006-2023 Bruno Silvestre
5 *
6 *--------------------------------------------------------------------------*/
7
8#include "compat.h"
9#include "options.h"
10#include "ec.h"
11
12/**
13 * Registre the module.
14 */
15LSEC_API int luaopen_ssl_config(lua_State *L)
16{
17 lsec_ssl_option_t *opt;
18
19 lua_newtable(L);
20
21 // Options
22 lua_pushstring(L, "options");
23 lua_newtable(L);
24 for (opt = lsec_get_ssl_options(); opt->name; opt++) {
25 lua_pushstring(L, opt->name);
26 lua_pushboolean(L, 1);
27 lua_rawset(L, -3);
28 }
29 lua_rawset(L, -3);
30
31 // Protocols
32 lua_pushstring(L, "protocols");
33 lua_newtable(L);
34
35 lua_pushstring(L, "tlsv1");
36 lua_pushboolean(L, 1);
37 lua_rawset(L, -3);
38 lua_pushstring(L, "tlsv1_1");
39 lua_pushboolean(L, 1);
40 lua_rawset(L, -3);
41 lua_pushstring(L, "tlsv1_2");
42 lua_pushboolean(L, 1);
43 lua_rawset(L, -3);
44#ifdef TLS1_3_VERSION
45 lua_pushstring(L, "tlsv1_3");
46 lua_pushboolean(L, 1);
47 lua_rawset(L, -3);
48#endif
49
50 lua_rawset(L, -3);
51
52 // Algorithms
53 lua_pushstring(L, "algorithms");
54 lua_newtable(L);
55
56#ifndef OPENSSL_NO_EC
57 lua_pushstring(L, "ec");
58 lua_pushboolean(L, 1);
59 lua_rawset(L, -3);
60#endif
61 lua_rawset(L, -3);
62
63 // Curves
64 lua_pushstring(L, "curves");
65 lsec_get_curves(L);
66 lua_rawset(L, -3);
67
68 // Capabilities
69 lua_pushstring(L, "capabilities");
70 lua_newtable(L);
71
72 // ALPN
73 lua_pushstring(L, "alpn");
74 lua_pushboolean(L, 1);
75 lua_rawset(L, -3);
76
77#ifdef LSEC_ENABLE_PSK
78 lua_pushstring(L, "psk");
79 lua_pushboolean(L, 1);
80 lua_rawset(L, -3);
81#endif
82
83#ifdef LSEC_ENABLE_DANE
84 // DANE
85 lua_pushstring(L, "dane");
86#ifdef DANE_FLAG_NO_DANE_EE_NAMECHECKS
87 lua_createtable(L, 0, 1);
88 lua_pushstring(L, "no_ee_namechecks");
89 lua_pushboolean(L, 1);
90 lua_rawset(L, -3);
91#else
92 lua_pushboolean(L, 1);
93#endif
94 lua_rawset(L, -3);
95#endif
96
97#ifndef OPENSSL_NO_EC
98 lua_pushstring(L, "curves_list");
99 lua_pushboolean(L, 1);
100 lua_rawset(L, -3);
101 lua_pushstring(L, "ecdh_auto");
102 lua_pushboolean(L, 1);
103 lua_rawset(L, -3);
104#endif
105 lua_rawset(L, -3);
106
107 return 1;
108}
diff --git a/vendor/luasec/src/context.c b/vendor/luasec/src/context.c
new file mode 100644
index 00000000..881ebb90
--- /dev/null
+++ b/vendor/luasec/src/context.c
@@ -0,0 +1,1099 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2014-2023 Kim Alvefur, Paul Aurich, Tobias Markmann, Matthew Wild
5 * Copyright (C) 2006-2023 Bruno Silvestre
6 *
7 *--------------------------------------------------------------------------*/
8
9#include <string.h>
10
11#if defined(WIN32)
12#include <windows.h>
13#endif
14
15#include <openssl/ssl.h>
16#include <openssl/err.h>
17#include <openssl/x509.h>
18#include <openssl/x509v3.h>
19#include <openssl/x509_vfy.h>
20#include <openssl/dh.h>
21
22#include <lua.h>
23#include <lauxlib.h>
24
25#include "compat.h"
26#include "context.h"
27#include "options.h"
28
29#ifndef OPENSSL_NO_EC
30#include <openssl/ec.h>
31#include "ec.h"
32#endif
33
34/*--------------------------- Auxiliary Functions ----------------------------*/
35
36/**
37 * Return the context.
38 */
39static p_context checkctx(lua_State *L, int idx)
40{
41 return (p_context)luaL_checkudata(L, idx, "SSL:Context");
42}
43
44static p_context testctx(lua_State *L, int idx)
45{
46 return (p_context)luaL_testudata(L, idx, "SSL:Context");
47}
48
49/**
50 * Prepare the SSL options flag.
51 */
52static int set_option_flag(const char *opt, unsigned long *flag)
53{
54 lsec_ssl_option_t *p;
55 for (p = lsec_get_ssl_options(); p->name; p++) {
56 if (!strcmp(opt, p->name)) {
57 *flag |= p->code;
58 return 1;
59 }
60 }
61 return 0;
62}
63
64#ifndef LSEC_API_OPENSSL_1_1_0
65/**
66 * Find the protocol.
67 */
68static const SSL_METHOD* str2method(const char *method, int *vmin, int *vmax)
69{
70 (void)vmin;
71 (void)vmax;
72 if (!strcmp(method, "any")) return SSLv23_method();
73 if (!strcmp(method, "sslv23")) return SSLv23_method(); // deprecated
74 if (!strcmp(method, "tlsv1")) return TLSv1_method();
75 if (!strcmp(method, "tlsv1_1")) return TLSv1_1_method();
76 if (!strcmp(method, "tlsv1_2")) return TLSv1_2_method();
77 return NULL;
78}
79
80#else
81
82/**
83 * Find the protocol.
84 */
85static const SSL_METHOD* str2method(const char *method, int *vmin, int *vmax)
86{
87 if (!strcmp(method, "any") || !strcmp(method, "sslv23")) { // 'sslv23' is deprecated
88 *vmin = 0;
89 *vmax = 0;
90 return TLS_method();
91 }
92 else if (!strcmp(method, "tlsv1")) {
93 *vmin = TLS1_VERSION;
94 *vmax = TLS1_VERSION;
95 return TLS_method();
96 }
97 else if (!strcmp(method, "tlsv1_1")) {
98 *vmin = TLS1_1_VERSION;
99 *vmax = TLS1_1_VERSION;
100 return TLS_method();
101 }
102 else if (!strcmp(method, "tlsv1_2")) {
103 *vmin = TLS1_2_VERSION;
104 *vmax = TLS1_2_VERSION;
105 return TLS_method();
106 }
107#if defined(TLS1_3_VERSION)
108 else if (!strcmp(method, "tlsv1_3")) {
109 *vmin = TLS1_3_VERSION;
110 *vmax = TLS1_3_VERSION;
111 return TLS_method();
112 }
113#endif
114 return NULL;
115}
116#endif
117
118/**
119 * Prepare the SSL handshake verify flag.
120 */
121static int set_verify_flag(const char *str, int *flag)
122{
123 if (!strcmp(str, "none")) {
124 *flag |= SSL_VERIFY_NONE;
125 return 1;
126 }
127 if (!strcmp(str, "peer")) {
128 *flag |= SSL_VERIFY_PEER;
129 return 1;
130 }
131 if (!strcmp(str, "client_once")) {
132 *flag |= SSL_VERIFY_CLIENT_ONCE;
133 return 1;
134 }
135 if (!strcmp(str, "fail_if_no_peer_cert")) {
136 *flag |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
137 return 1;
138 }
139 return 0;
140}
141
142/**
143 * Password callback for reading the private key.
144 */
145static int passwd_cb(char *buf, int size, int flag, void *udata)
146{
147 lua_State *L = (lua_State*)udata;
148 switch (lua_type(L, 3)) {
149 case LUA_TFUNCTION:
150 lua_pushvalue(L, 3);
151 lua_call(L, 0, 1);
152 if (lua_type(L, -1) != LUA_TSTRING) {
153 lua_pop(L, 1); /* Remove the result from the stack */
154 return 0;
155 }
156 /* fallback */
157 case LUA_TSTRING:
158 strncpy(buf, lua_tostring(L, -1), size);
159 lua_pop(L, 1); /* Remove the result from the stack */
160 buf[size-1] = '\0';
161 return (int)strlen(buf);
162 }
163 return 0;
164}
165
166/**
167 * Add an error related to a depth certificate of the chain.
168 */
169static void add_cert_error(lua_State *L, SSL *ssl, int err, int depth)
170{
171 luaL_getmetatable(L, "SSL:Verify:Registry");
172 lua_pushlightuserdata(L, (void*)ssl);
173 lua_gettable(L, -2);
174 if (lua_isnil(L, -1)) {
175 lua_pop(L, 1);
176 /* Create an error table for this connection */
177 lua_newtable(L);
178 lua_pushlightuserdata(L, (void*)ssl);
179 lua_pushvalue(L, -2); /* keep the table on stack */
180 lua_settable(L, -4);
181 }
182 lua_rawgeti(L, -1, depth+1);
183 /* If the table doesn't exist, create it */
184 if (lua_isnil(L, -1)) {
185 lua_pop(L, 1); /* remove 'nil' from stack */
186 lua_newtable(L);
187 lua_pushvalue(L, -1); /* keep the table on stack */
188 lua_rawseti(L, -3, depth+1);
189 }
190 lua_pushstring(L, X509_verify_cert_error_string(err));
191 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
192 /* Clear the stack */
193 lua_pop(L, 3);
194}
195
196/**
197 * Call Lua user function to get the DH key.
198 */
199static DH *dhparam_cb(SSL *ssl, int is_export, int keylength)
200{
201 BIO *bio;
202 lua_State *L;
203 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
204 p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
205
206 L = pctx->L;
207
208 /* Get the callback */
209 luaL_getmetatable(L, "SSL:DH:Registry");
210 lua_pushlightuserdata(L, (void*)ctx);
211 lua_gettable(L, -2);
212
213 /* Invoke the callback */
214 lua_pushboolean(L, is_export);
215 lua_pushnumber(L, keylength);
216 lua_call(L, 2, 1);
217
218 /* Load parameters from returned value */
219 if (lua_type(L, -1) != LUA_TSTRING) {
220 lua_pop(L, 2); /* Remove values from stack */
221 return NULL;
222 }
223
224 bio = BIO_new_mem_buf((void*)lua_tostring(L, -1), lua_rawlen(L, -1));
225 if (bio) {
226 pctx->dh_param = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
227 BIO_free(bio);
228 }
229
230 lua_pop(L, 2); /* Remove values from stack */
231 return pctx->dh_param;
232}
233
234/**
235 * Set the "ignore purpose" before to start verifing the certificate chain.
236 */
237static int cert_verify_cb(X509_STORE_CTX *x509_ctx, void *ptr)
238{
239 int verify;
240 lua_State *L;
241 SSL_CTX *ctx = (SSL_CTX*)ptr;
242 p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
243
244 L = pctx->L;
245
246 /* Get verify flags */
247 luaL_getmetatable(L, "SSL:Verify:Registry");
248 lua_pushlightuserdata(L, (void*)ctx);
249 lua_gettable(L, -2);
250 verify = (int)lua_tonumber(L, -1);
251
252 lua_pop(L, 2); /* Remove values from stack */
253
254 if (verify & LSEC_VERIFY_IGNORE_PURPOSE) {
255 /* Set parameters to ignore the server purpose */
256 X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(x509_ctx);
257 if (param) {
258 X509_VERIFY_PARAM_set_purpose(param, X509_PURPOSE_SSL_SERVER);
259 X509_VERIFY_PARAM_set_trust(param, X509_TRUST_SSL_SERVER);
260 }
261 }
262 /* Call OpenSSL standard verification function */
263 return X509_verify_cert(x509_ctx);
264}
265
266/**
267 * This callback implements the "continue on error" flag and log the errors.
268 */
269static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
270{
271 int err;
272 int verify;
273 SSL *ssl;
274 SSL_CTX *ctx;
275 p_context pctx;
276 lua_State *L;
277
278 /* Short-circuit optimization */
279 if (preverify_ok)
280 return 1;
281
282 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
283 SSL_get_ex_data_X509_STORE_CTX_idx());
284 ctx = SSL_get_SSL_CTX(ssl);
285 pctx = (p_context)SSL_CTX_get_app_data(ctx);
286 L = pctx->L;
287
288 /* Get verify flags */
289 luaL_getmetatable(L, "SSL:Verify:Registry");
290 lua_pushlightuserdata(L, (void*)ctx);
291 lua_gettable(L, -2);
292 verify = (int)lua_tonumber(L, -1);
293
294 lua_pop(L, 2); /* Remove values from stack */
295
296 err = X509_STORE_CTX_get_error(x509_ctx);
297 if (err != X509_V_OK)
298 add_cert_error(L, ssl, err, X509_STORE_CTX_get_error_depth(x509_ctx));
299
300 return (verify & LSEC_VERIFY_CONTINUE ? 1 : preverify_ok);
301}
302
303/*------------------------------ Lua Functions -------------------------------*/
304
305/**
306 * Create a SSL context.
307 */
308static int create(lua_State *L)
309{
310 p_context ctx;
311 const char *str_method;
312 const SSL_METHOD *method;
313 int vmin, vmax;
314
315 str_method = luaL_checkstring(L, 1);
316 method = str2method(str_method, &vmin, &vmax);
317 if (!method) {
318 lua_pushnil(L);
319 lua_pushfstring(L, "invalid protocol (%s)", str_method);
320 return 2;
321 }
322 ctx = (p_context) lua_newuserdata(L, sizeof(t_context));
323 if (!ctx) {
324 lua_pushnil(L);
325 lua_pushstring(L, "error creating context");
326 return 2;
327 }
328 memset(ctx, 0, sizeof(t_context));
329 ctx->context = SSL_CTX_new(method);
330 if (!ctx->context) {
331 lua_pushnil(L);
332 lua_pushfstring(L, "error creating context (%s)",
333 ERR_reason_error_string(ERR_get_error()));
334 return 2;
335 }
336#ifdef LSEC_API_OPENSSL_1_1_0
337 SSL_CTX_set_min_proto_version(ctx->context, vmin);
338 SSL_CTX_set_max_proto_version(ctx->context, vmax);
339#endif
340 ctx->mode = LSEC_MODE_INVALID;
341 ctx->L = L;
342 luaL_getmetatable(L, "SSL:Context");
343 lua_setmetatable(L, -2);
344
345 /* No session support */
346 SSL_CTX_set_session_cache_mode(ctx->context, SSL_SESS_CACHE_OFF);
347 /* Link LuaSec context with the OpenSSL context */
348 SSL_CTX_set_app_data(ctx->context, ctx);
349
350 return 1;
351}
352
353/**
354 * Load the trusting certificates.
355 */
356static int load_locations(lua_State *L)
357{
358 SSL_CTX *ctx = lsec_checkcontext(L, 1);
359 const char *cafile = luaL_optstring(L, 2, NULL);
360 const char *capath = luaL_optstring(L, 3, NULL);
361 if (SSL_CTX_load_verify_locations(ctx, cafile, capath) != 1) {
362 lua_pushboolean(L, 0);
363 lua_pushfstring(L, "error loading CA locations (%s)",
364 ERR_reason_error_string(ERR_get_error()));
365 return 2;
366 }
367 lua_pushboolean(L, 1);
368 return 1;
369}
370
371/**
372 * Load the certificate file.
373 */
374static int load_cert(lua_State *L)
375{
376 SSL_CTX *ctx = lsec_checkcontext(L, 1);
377 const char *filename = luaL_checkstring(L, 2);
378 if (SSL_CTX_use_certificate_chain_file(ctx, filename) != 1) {
379 lua_pushboolean(L, 0);
380 lua_pushfstring(L, "error loading certificate (%s)",
381 ERR_reason_error_string(ERR_get_error()));
382 return 2;
383 }
384 lua_pushboolean(L, 1);
385 return 1;
386}
387
388/**
389 * Load the key file -- only in PEM format.
390 */
391static int load_key(lua_State *L)
392{
393 int ret = 1;
394 SSL_CTX *ctx = lsec_checkcontext(L, 1);
395 const char *filename = luaL_checkstring(L, 2);
396 switch (lua_type(L, 3)) {
397 case LUA_TSTRING:
398 case LUA_TFUNCTION:
399 SSL_CTX_set_default_passwd_cb(ctx, passwd_cb);
400 SSL_CTX_set_default_passwd_cb_userdata(ctx, L);
401 /* fallback */
402 case LUA_TNIL:
403 if (SSL_CTX_use_PrivateKey_file(ctx, filename, SSL_FILETYPE_PEM) == 1)
404 lua_pushboolean(L, 1);
405 else {
406 ret = 2;
407 lua_pushboolean(L, 0);
408 lua_pushfstring(L, "error loading private key (%s)",
409 ERR_reason_error_string(ERR_get_error()));
410 }
411 SSL_CTX_set_default_passwd_cb(ctx, NULL);
412 SSL_CTX_set_default_passwd_cb_userdata(ctx, NULL);
413 break;
414 default:
415 lua_pushstring(L, "invalid callback value");
416 lua_error(L);
417 }
418 return ret;
419}
420
421/**
422 * Check that the certificate public key matches the private key
423 */
424
425static int check_key(lua_State *L)
426{
427 SSL_CTX *ctx = lsec_checkcontext(L, 1);
428 lua_pushboolean(L, SSL_CTX_check_private_key(ctx));
429 return 1;
430}
431
432/**
433 * Set the cipher list.
434 */
435static int set_cipher(lua_State *L)
436{
437 SSL_CTX *ctx = lsec_checkcontext(L, 1);
438 const char *list = luaL_checkstring(L, 2);
439 if (SSL_CTX_set_cipher_list(ctx, list) != 1) {
440 lua_pushboolean(L, 0);
441 lua_pushfstring(L, "error setting cipher list (%s)", ERR_reason_error_string(ERR_get_error()));
442 return 2;
443 }
444 lua_pushboolean(L, 1);
445 return 1;
446}
447
448/**
449 * Set the cipher suites.
450 */
451static int set_ciphersuites(lua_State *L)
452{
453#if defined(TLS1_3_VERSION)
454 SSL_CTX *ctx = lsec_checkcontext(L, 1);
455 const char *list = luaL_checkstring(L, 2);
456 if (SSL_CTX_set_ciphersuites(ctx, list) != 1) {
457 lua_pushboolean(L, 0);
458 lua_pushfstring(L, "error setting cipher list (%s)", ERR_reason_error_string(ERR_get_error()));
459 return 2;
460 }
461#endif
462 lua_pushboolean(L, 1);
463 return 1;
464}
465
466/**
467 * Set the depth for certificate checking.
468 */
469static int set_depth(lua_State *L)
470{
471 SSL_CTX *ctx = lsec_checkcontext(L, 1);
472 SSL_CTX_set_verify_depth(ctx, (int)luaL_checkinteger(L, 2));
473 lua_pushboolean(L, 1);
474 return 1;
475}
476
477/**
478 * Set the handshake verify options.
479 */
480static int set_verify(lua_State *L)
481{
482 int i;
483 const char *str;
484 int flag = 0;
485 SSL_CTX *ctx = lsec_checkcontext(L, 1);
486 int max = lua_gettop(L);
487 for (i = 2; i <= max; i++) {
488 str = luaL_checkstring(L, i);
489 if (!set_verify_flag(str, &flag)) {
490 lua_pushboolean(L, 0);
491 lua_pushfstring(L, "invalid verify option (%s)", str);
492 return 2;
493 }
494 }
495 if (flag) SSL_CTX_set_verify(ctx, flag, NULL);
496 lua_pushboolean(L, 1);
497 return 1;
498}
499
500/**
501 * Set the protocol options.
502 */
503static int set_options(lua_State *L)
504{
505 int i;
506 const char *str;
507 unsigned long flag = 0L;
508 SSL_CTX *ctx = lsec_checkcontext(L, 1);
509 int max = lua_gettop(L);
510 /* any option? */
511 if (max > 1) {
512 for (i = 2; i <= max; i++) {
513 str = luaL_checkstring(L, i);
514 if (!set_option_flag(str, &flag)) {
515 lua_pushboolean(L, 0);
516 lua_pushfstring(L, "invalid option (%s)", str);
517 return 2;
518 }
519 }
520 SSL_CTX_set_options(ctx, flag);
521 }
522 lua_pushboolean(L, 1);
523 return 1;
524}
525
526/**
527 * Set the context mode.
528 */
529static int set_mode(lua_State *L)
530{
531 p_context ctx = checkctx(L, 1);
532 const char *str = luaL_checkstring(L, 2);
533 if (!strcmp("server", str)) {
534 ctx->mode = LSEC_MODE_SERVER;
535 lua_pushboolean(L, 1);
536 return 1;
537 }
538 if (!strcmp("client", str)) {
539 ctx->mode = LSEC_MODE_CLIENT;
540 lua_pushboolean(L, 1);
541 return 1;
542 }
543 lua_pushboolean(L, 0);
544 lua_pushfstring(L, "invalid mode (%s)", str);
545 return 1;
546}
547
548/**
549 * Configure DH parameters.
550 */
551static int set_dhparam(lua_State *L)
552{
553 SSL_CTX *ctx = lsec_checkcontext(L, 1);
554 SSL_CTX_set_tmp_dh_callback(ctx, dhparam_cb);
555
556 /* Save callback */
557 luaL_getmetatable(L, "SSL:DH:Registry");
558 lua_pushlightuserdata(L, (void*)ctx);
559 lua_pushvalue(L, 2);
560 lua_settable(L, -3);
561
562 return 0;
563}
564
565#if !defined(OPENSSL_NO_EC)
566/**
567 * Set elliptic curve.
568 */
569static int set_curve(lua_State *L)
570{
571 long ret;
572 EC_KEY *key = NULL;
573 SSL_CTX *ctx = lsec_checkcontext(L, 1);
574 const char *str = luaL_checkstring(L, 2);
575
576 SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
577
578 key = lsec_find_ec_key(L, str);
579
580 if (!key) {
581 lua_pushboolean(L, 0);
582 lua_pushfstring(L, "elliptic curve '%s' not supported", str);
583 return 2;
584 }
585
586 ret = SSL_CTX_set_tmp_ecdh(ctx, key);
587 /* SSL_CTX_set_tmp_ecdh takes its own reference */
588 EC_KEY_free(key);
589
590 if (!ret) {
591 lua_pushboolean(L, 0);
592 lua_pushfstring(L, "error setting elliptic curve (%s)",
593 ERR_reason_error_string(ERR_get_error()));
594 return 2;
595 }
596
597 lua_pushboolean(L, 1);
598 return 1;
599}
600
601/**
602 * Set elliptic curves list.
603 */
604static int set_curves_list(lua_State *L)
605{
606 SSL_CTX *ctx = lsec_checkcontext(L, 1);
607 const char *str = luaL_checkstring(L, 2);
608
609 SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
610
611 if (SSL_CTX_set1_curves_list(ctx, str) != 1) {
612 lua_pushboolean(L, 0);
613 lua_pushfstring(L, "unknown elliptic curve in \"%s\"", str);
614 return 2;
615 }
616
617#if defined(LIBRESSL_VERSION_NUMBER) || !defined(LSEC_API_OPENSSL_1_1_0)
618 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
619#endif
620
621 lua_pushboolean(L, 1);
622 return 1;
623}
624#endif
625
626/**
627 * Set the protocols a client should send for ALPN.
628 */
629static int set_alpn(lua_State *L)
630{
631 long ret;
632 size_t len;
633 p_context ctx = checkctx(L, 1);
634 const char *str = luaL_checklstring(L, 2, &len);
635
636 ret = SSL_CTX_set_alpn_protos(ctx->context, (const unsigned char*)str, len);
637 if (ret) {
638 lua_pushboolean(L, 0);
639 lua_pushfstring(L, "error setting ALPN (%s)", ERR_reason_error_string(ERR_get_error()));
640 return 2;
641 }
642 lua_pushboolean(L, 1);
643 return 1;
644}
645
646/**
647 * This standard callback calls the server's callback in Lua sapce.
648 * The server has to return a list in wire-format strings.
649 * This function uses a helper function to match server and client lists.
650 */
651static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
652 const unsigned char *in, unsigned int inlen, void *arg)
653{
654 int ret;
655 size_t server_len;
656 const char *server;
657 p_context ctx = (p_context)arg;
658 lua_State *L = ctx->L;
659
660 luaL_getmetatable(L, "SSL:ALPN:Registry");
661 lua_pushlightuserdata(L, (void*)ctx->context);
662 lua_gettable(L, -2);
663
664 lua_pushlstring(L, (const char*)in, inlen);
665
666 lua_call(L, 1, 1);
667
668 if (!lua_isstring(L, -1)) {
669 lua_pop(L, 2);
670 return SSL_TLSEXT_ERR_NOACK;
671 }
672
673 // Protocol list from server in wire-format string
674 server = luaL_checklstring(L, -1, &server_len);
675 ret = SSL_select_next_proto((unsigned char**)out, outlen, (const unsigned char*)server,
676 server_len, in, inlen);
677 if (ret != OPENSSL_NPN_NEGOTIATED) {
678 lua_pop(L, 2);
679 return SSL_TLSEXT_ERR_NOACK;
680 }
681
682 // Copy the result because lua_pop() can collect the pointer
683 ctx->alpn = malloc(*outlen);
684 memcpy(ctx->alpn, (void*)*out, *outlen);
685 *out = (const unsigned char*)ctx->alpn;
686
687 lua_pop(L, 2);
688
689 return SSL_TLSEXT_ERR_OK;
690}
691
692/**
693 * Set a callback a server can use to select the next protocol with ALPN.
694 */
695static int set_alpn_cb(lua_State *L)
696{
697 p_context ctx = checkctx(L, 1);
698
699 luaL_getmetatable(L, "SSL:ALPN:Registry");
700 lua_pushlightuserdata(L, (void*)ctx->context);
701 lua_pushvalue(L, 2);
702 lua_settable(L, -3);
703
704 SSL_CTX_set_alpn_select_cb(ctx->context, alpn_cb, ctx);
705
706 lua_pushboolean(L, 1);
707 return 1;
708}
709
710#if defined(LSEC_ENABLE_PSK)
711/**
712 * Callback to select the PSK.
713 */
714static unsigned int server_psk_cb(SSL *ssl, const char *identity, unsigned char *psk,
715 unsigned int max_psk_len)
716{
717 size_t psk_len;
718 const char *ret_psk;
719 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
720 p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
721 lua_State *L = pctx->L;
722
723 luaL_getmetatable(L, "SSL:PSK:Registry");
724 lua_pushlightuserdata(L, (void*)pctx->context);
725 lua_gettable(L, -2);
726
727 lua_pushstring(L, identity);
728 lua_pushinteger(L, max_psk_len);
729
730 lua_call(L, 2, 1);
731
732 if (!lua_isstring(L, -1)) {
733 lua_pop(L, 2);
734 return 0;
735 }
736
737 ret_psk = lua_tolstring(L, -1, &psk_len);
738
739 if (psk_len == 0 || psk_len > max_psk_len)
740 psk_len = 0;
741 else
742 memcpy(psk, ret_psk, psk_len);
743
744 lua_pop(L, 2);
745
746 return psk_len;
747}
748
749/**
750 * Set a PSK callback for server.
751 */
752static int set_server_psk_cb(lua_State *L)
753{
754 p_context ctx = checkctx(L, 1);
755
756 luaL_getmetatable(L, "SSL:PSK:Registry");
757 lua_pushlightuserdata(L, (void*)ctx->context);
758 lua_pushvalue(L, 2);
759 lua_settable(L, -3);
760
761 SSL_CTX_set_psk_server_callback(ctx->context, server_psk_cb);
762
763 lua_pushboolean(L, 1);
764 return 1;
765}
766
767/*
768 * Set the PSK indentity hint.
769 */
770static int set_psk_identity_hint(lua_State *L)
771{
772 p_context ctx = checkctx(L, 1);
773 const char *hint = luaL_checkstring(L, 2);
774 int ret = SSL_CTX_use_psk_identity_hint(ctx->context, hint);
775 lua_pushboolean(L, ret);
776 return 1;
777}
778
779/*
780 * Client callback to PSK.
781 */
782static unsigned int client_psk_cb(SSL *ssl, const char *hint, char *identity,
783 unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len)
784{
785 size_t psk_len;
786 size_t identity_len;
787 const char *ret_psk;
788 const char *ret_identity;
789 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
790 p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
791 lua_State *L = pctx->L;
792
793 luaL_getmetatable(L, "SSL:PSK:Registry");
794 lua_pushlightuserdata(L, (void*)pctx->context);
795 lua_gettable(L, -2);
796
797 if (hint)
798 lua_pushstring(L, hint);
799 else
800 lua_pushnil(L);
801
802 // Leave space to '\0'
803 lua_pushinteger(L, max_identity_len-1);
804 lua_pushinteger(L, max_psk_len);
805
806 lua_call(L, 3, 2);
807
808 if (!lua_isstring(L, -1) || !lua_isstring(L, -2)) {
809 lua_pop(L, 3);
810 return 0;
811 }
812
813 ret_identity = lua_tolstring(L, -2, &identity_len);
814 ret_psk = lua_tolstring(L, -1, &psk_len);
815
816 if (identity_len >= max_identity_len || psk_len > max_psk_len)
817 psk_len = 0;
818 else {
819 memcpy(identity, ret_identity, identity_len);
820 identity[identity_len] = 0;
821 memcpy(psk, ret_psk, psk_len);
822 }
823
824 lua_pop(L, 3);
825
826 return psk_len;
827}
828
829/**
830 * Set a PSK callback for client.
831 */
832static int set_client_psk_cb(lua_State *L) {
833 p_context ctx = checkctx(L, 1);
834
835 luaL_getmetatable(L, "SSL:PSK:Registry");
836 lua_pushlightuserdata(L, (void*)ctx->context);
837 lua_pushvalue(L, 2);
838 lua_settable(L, -3);
839
840 SSL_CTX_set_psk_client_callback(ctx->context, client_psk_cb);
841
842 lua_pushboolean(L, 1);
843 return 1;
844}
845#endif
846
847#if defined(LSEC_ENABLE_DANE)
848/*
849 * DANE
850 */
851static int dane_options[] = {
852 /* TODO move into options.c
853 * however this symbol is not from openssl/ssl.h but rather from
854 * openssl/x509_vfy.h
855 * */
856#ifdef DANE_FLAG_NO_DANE_EE_NAMECHECKS
857 DANE_FLAG_NO_DANE_EE_NAMECHECKS,
858#endif
859 0
860};
861static const char *dane_option_names[] = {
862#ifdef DANE_FLAG_NO_DANE_EE_NAMECHECKS
863 "no_ee_namechecks",
864#endif
865 NULL
866};
867
868static int set_dane(lua_State *L)
869{
870 int ret, i;
871 SSL_CTX *ctx = lsec_checkcontext(L, 1);
872 ret = SSL_CTX_dane_enable(ctx);
873 for (i = 2; ret > 0 && i <= lua_gettop(L); i++) {
874 ret = SSL_CTX_dane_set_flags(ctx, dane_options[luaL_checkoption(L, i, NULL, dane_option_names)]);
875 }
876 lua_pushboolean(L, (ret > 0));
877 return 1;
878}
879#endif
880
881/**
882 * Package functions
883 */
884static luaL_Reg funcs[] = {
885 {"create", create},
886 {"locations", load_locations},
887 {"loadcert", load_cert},
888 {"loadkey", load_key},
889 {"checkkey", check_key},
890 {"setalpn", set_alpn},
891 {"setalpncb", set_alpn_cb},
892 {"setcipher", set_cipher},
893 {"setciphersuites", set_ciphersuites},
894 {"setdepth", set_depth},
895 {"setdhparam", set_dhparam},
896 {"setverify", set_verify},
897 {"setoptions", set_options},
898#if defined(LSEC_ENABLE_PSK)
899 {"setpskhint", set_psk_identity_hint},
900 {"setserverpskcb", set_server_psk_cb},
901 {"setclientpskcb", set_client_psk_cb},
902#endif
903 {"setmode", set_mode},
904#if !defined(OPENSSL_NO_EC)
905 {"setcurve", set_curve},
906 {"setcurveslist", set_curves_list},
907#endif
908#if defined(LSEC_ENABLE_DANE)
909 {"setdane", set_dane},
910#endif
911 {NULL, NULL}
912};
913
914/*-------------------------------- Metamethods -------------------------------*/
915
916/**
917 * Collect SSL context -- GC metamethod.
918 */
919static int meth_destroy(lua_State *L)
920{
921 p_context ctx = checkctx(L, 1);
922 if (ctx->context) {
923 /* Clear registries */
924 luaL_getmetatable(L, "SSL:DH:Registry");
925 lua_pushlightuserdata(L, (void*)ctx->context);
926 lua_pushnil(L);
927 lua_settable(L, -3);
928 luaL_getmetatable(L, "SSL:Verify:Registry");
929 lua_pushlightuserdata(L, (void*)ctx->context);
930 lua_pushnil(L);
931 lua_settable(L, -3);
932 luaL_getmetatable(L, "SSL:ALPN:Registry");
933 lua_pushlightuserdata(L, (void*)ctx->context);
934 lua_pushnil(L);
935 lua_settable(L, -3);
936 luaL_getmetatable(L, "SSL:PSK:Registry");
937 lua_pushlightuserdata(L, (void*)ctx->context);
938 lua_pushnil(L);
939 lua_settable(L, -3);
940
941 SSL_CTX_free(ctx->context);
942 ctx->context = NULL;
943 }
944 return 0;
945}
946
947/**
948 * Object information -- tostring metamethod.
949 */
950static int meth_tostring(lua_State *L)
951{
952 p_context ctx = checkctx(L, 1);
953 lua_pushfstring(L, "SSL context: %p", ctx);
954 return 1;
955}
956
957/**
958 * Set extra flags for handshake verification.
959 */
960static int meth_set_verify_ext(lua_State *L)
961{
962 int i;
963 const char *str;
964 int crl_flag = 0;
965 int lsec_flag = 0;
966 SSL_CTX *ctx = lsec_checkcontext(L, 1);
967 int max = lua_gettop(L);
968 for (i = 2; i <= max; i++) {
969 str = luaL_checkstring(L, i);
970 if (!strcmp(str, "lsec_continue")) {
971 lsec_flag |= LSEC_VERIFY_CONTINUE;
972 } else if (!strcmp(str, "lsec_ignore_purpose")) {
973 lsec_flag |= LSEC_VERIFY_IGNORE_PURPOSE;
974 } else if (!strcmp(str, "crl_check")) {
975 crl_flag |= X509_V_FLAG_CRL_CHECK;
976 } else if (!strcmp(str, "crl_check_chain")) {
977 crl_flag |= X509_V_FLAG_CRL_CHECK_ALL;
978 } else {
979 lua_pushboolean(L, 0);
980 lua_pushfstring(L, "invalid verify option (%s)", str);
981 return 2;
982 }
983 }
984 /* Set callback? */
985 if (lsec_flag) {
986 SSL_CTX_set_verify(ctx, SSL_CTX_get_verify_mode(ctx), verify_cb);
987 SSL_CTX_set_cert_verify_callback(ctx, cert_verify_cb, (void*)ctx);
988 /* Save flag */
989 luaL_getmetatable(L, "SSL:Verify:Registry");
990 lua_pushlightuserdata(L, (void*)ctx);
991 lua_pushnumber(L, lsec_flag);
992 lua_settable(L, -3);
993 } else {
994 SSL_CTX_set_verify(ctx, SSL_CTX_get_verify_mode(ctx), NULL);
995 SSL_CTX_set_cert_verify_callback(ctx, NULL, NULL);
996 /* Remove flag */
997 luaL_getmetatable(L, "SSL:Verify:Registry");
998 lua_pushlightuserdata(L, (void*)ctx);
999 lua_pushnil(L);
1000 lua_settable(L, -3);
1001 }
1002
1003 /* X509 flag */
1004 X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), crl_flag);
1005
1006 /* Ok */
1007 lua_pushboolean(L, 1);
1008 return 1;
1009}
1010
1011/**
1012 * Context metamethods.
1013 */
1014static luaL_Reg meta[] = {
1015 {"__close", meth_destroy},
1016 {"__gc", meth_destroy},
1017 {"__tostring", meth_tostring},
1018 {NULL, NULL}
1019};
1020
1021/**
1022 * Index metamethods.
1023 */
1024static luaL_Reg meta_index[] = {
1025 {"setverifyext", meth_set_verify_ext},
1026 {NULL, NULL}
1027};
1028
1029
1030/*----------------------------- Public Functions ---------------------------*/
1031
1032/**
1033 * Retrieve the SSL context from the Lua stack.
1034 */
1035SSL_CTX* lsec_checkcontext(lua_State *L, int idx)
1036{
1037 p_context ctx = checkctx(L, idx);
1038 return ctx->context;
1039}
1040
1041SSL_CTX* lsec_testcontext(lua_State *L, int idx)
1042{
1043 p_context ctx = testctx(L, idx);
1044 return (ctx) ? ctx->context : NULL;
1045}
1046
1047/**
1048 * Retrieve the mode from the context in the Lua stack.
1049 */
1050int lsec_getmode(lua_State *L, int idx)
1051{
1052 p_context ctx = checkctx(L, idx);
1053 return ctx->mode;
1054}
1055
1056/*-- Compat - Lua 5.1 --*/
1057#if (LUA_VERSION_NUM == 501)
1058
1059void *lsec_testudata (lua_State *L, int ud, const char *tname) {
1060 void *p = lua_touserdata(L, ud);
1061 if (p != NULL) { /* value is a userdata? */
1062 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
1063 luaL_getmetatable(L, tname); /* get correct metatable */
1064 if (!lua_rawequal(L, -1, -2)) /* not the same? */
1065 p = NULL; /* value is a userdata with wrong metatable */
1066 lua_pop(L, 2); /* remove both metatables */
1067 return p;
1068 }
1069 }
1070 return NULL; /* value is not a userdata with a metatable */
1071}
1072
1073#endif
1074
1075/*------------------------------ Initialization ------------------------------*/
1076
1077/**
1078 * Registre the module.
1079 */
1080LSEC_API int luaopen_ssl_context(lua_State *L)
1081{
1082 luaL_newmetatable(L, "SSL:DH:Registry"); /* Keep all DH callbacks */
1083 luaL_newmetatable(L, "SSL:ALPN:Registry"); /* Keep all ALPN callbacks */
1084 luaL_newmetatable(L, "SSL:PSK:Registry"); /* Keep all PSK callbacks */
1085 luaL_newmetatable(L, "SSL:Verify:Registry"); /* Keep all verify flags */
1086 luaL_newmetatable(L, "SSL:Context");
1087 setfuncs(L, meta);
1088
1089 /* Create __index metamethods for context */
1090 luaL_newlib(L, meta_index);
1091 lua_setfield(L, -2, "__index");
1092
1093 lsec_load_curves(L);
1094
1095 /* Return the module */
1096 luaL_newlib(L, funcs);
1097
1098 return 1;
1099}
diff --git a/vendor/luasec/src/context.h b/vendor/luasec/src/context.h
new file mode 100644
index 00000000..dd6bd098
--- /dev/null
+++ b/vendor/luasec/src/context.h
@@ -0,0 +1,47 @@
1#ifndef LSEC_CONTEXT_H
2#define LSEC_CONTEXT_H
3
4/*--------------------------------------------------------------------------
5 * LuaSec 1.3.2
6 *
7 * Copyright (C) 2006-2023 Bruno Silvestre
8 *
9 *--------------------------------------------------------------------------*/
10
11#include <lua.h>
12#include <openssl/ssl.h>
13
14#include "compat.h"
15
16#define LSEC_MODE_INVALID 0
17#define LSEC_MODE_SERVER 1
18#define LSEC_MODE_CLIENT 2
19
20#define LSEC_VERIFY_CONTINUE 1
21#define LSEC_VERIFY_IGNORE_PURPOSE 2
22
23typedef struct t_context_ {
24 SSL_CTX *context;
25 lua_State *L;
26 DH *dh_param;
27 void *alpn;
28 int mode;
29} t_context;
30typedef t_context* p_context;
31
32/* Retrieve the SSL context from the Lua stack */
33SSL_CTX *lsec_checkcontext(lua_State *L, int idx);
34SSL_CTX *lsec_testcontext(lua_State *L, int idx);
35
36/* Retrieve the mode from the context in the Lua stack */
37int lsec_getmode(lua_State *L, int idx);
38
39/* Registre the module. */
40LSEC_API int luaopen_ssl_context(lua_State *L);
41
42/* Compat - Lua 5.1 */
43#if (LUA_VERSION_NUM == 501)
44void *lsec_testudata (lua_State *L, int ud, const char *tname);
45#endif
46
47#endif
diff --git a/vendor/luasec/src/ec.c b/vendor/luasec/src/ec.c
new file mode 100644
index 00000000..c7025a55
--- /dev/null
+++ b/vendor/luasec/src/ec.c
@@ -0,0 +1,116 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2006-2023 Bruno Silvestre
5 *
6 *--------------------------------------------------------------------------*/
7
8#include <openssl/objects.h>
9
10#include "ec.h"
11
12#ifndef OPENSSL_NO_EC
13
14EC_KEY *lsec_find_ec_key(lua_State *L, const char *str)
15{
16 int nid;
17 lua_pushstring(L, "SSL:EC:CURVES");
18 lua_rawget(L, LUA_REGISTRYINDEX);
19 lua_pushstring(L, str);
20 lua_rawget(L, -2);
21
22 if (!lua_isnumber(L, -1))
23 return NULL;
24
25 nid = (int)lua_tonumber(L, -1);
26 return EC_KEY_new_by_curve_name(nid);
27}
28
29void lsec_load_curves(lua_State *L)
30{
31 size_t i;
32 size_t size;
33 const char *name;
34 EC_builtin_curve *curves = NULL;
35
36 lua_pushstring(L, "SSL:EC:CURVES");
37 lua_newtable(L);
38
39 size = EC_get_builtin_curves(NULL, 0);
40 if (size > 0) {
41 curves = (EC_builtin_curve*)malloc(sizeof(EC_builtin_curve) * size);
42 EC_get_builtin_curves(curves, size);
43 for (i = 0; i < size; i++) {
44 name = OBJ_nid2sn(curves[i].nid);
45 if (name != NULL) {
46 lua_pushstring(L, name);
47 lua_pushnumber(L, curves[i].nid);
48 lua_rawset(L, -3);
49 }
50 switch (curves[i].nid) {
51 case NID_X9_62_prime256v1:
52 lua_pushstring(L, "P-256");
53 lua_pushnumber(L, curves[i].nid);
54 lua_rawset(L, -3);
55 break;
56 case NID_secp384r1:
57 lua_pushstring(L, "P-384");
58 lua_pushnumber(L, curves[i].nid);
59 lua_rawset(L, -3);
60 break;
61 case NID_secp521r1:
62 lua_pushstring(L, "P-521");
63 lua_pushnumber(L, curves[i].nid);
64 lua_rawset(L, -3);
65 break;
66 }
67 }
68 free(curves);
69 }
70
71 /* These are special so are manually added here */
72#ifdef NID_X25519
73 lua_pushstring(L, "X25519");
74 lua_pushnumber(L, NID_X25519);
75 lua_rawset(L, -3);
76#endif
77
78#ifdef NID_X448
79 lua_pushstring(L, "X448");
80 lua_pushnumber(L, NID_X448);
81 lua_rawset(L, -3);
82#endif
83
84 lua_rawset(L, LUA_REGISTRYINDEX);
85}
86
87void lsec_get_curves(lua_State *L)
88{
89 lua_newtable(L);
90
91 lua_pushstring(L, "SSL:EC:CURVES");
92 lua_rawget(L, LUA_REGISTRYINDEX);
93
94 lua_pushnil(L);
95 while (lua_next(L, -2) != 0) {
96 lua_pop(L, 1);
97 lua_pushvalue(L, -1);
98 lua_pushboolean(L, 1);
99 lua_rawset(L, -5);
100 }
101 lua_pop(L, 1);
102}
103
104#else
105
106void lsec_load_curves(lua_State *L)
107{
108 // do nothing
109}
110
111void lsec_get_curves(lua_State *L)
112{
113 lua_newtable(L);
114}
115
116#endif
diff --git a/vendor/luasec/src/ec.h b/vendor/luasec/src/ec.h
new file mode 100644
index 00000000..16d29360
--- /dev/null
+++ b/vendor/luasec/src/ec.h
@@ -0,0 +1,22 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2006-2023 Bruno Silvestre
5 *
6 *--------------------------------------------------------------------------*/
7
8#ifndef LSEC_EC_H
9#define LSEC_EC_H
10
11#include <lua.h>
12
13#ifndef OPENSSL_NO_EC
14#include <openssl/ec.h>
15
16EC_KEY *lsec_find_ec_key(lua_State *L, const char *str);
17#endif
18
19void lsec_get_curves(lua_State *L);
20void lsec_load_curves(lua_State *L);
21
22#endif
diff --git a/vendor/luasec/src/https.lua b/vendor/luasec/src/https.lua
new file mode 100644
index 00000000..85cef361
--- /dev/null
+++ b/vendor/luasec/src/https.lua
@@ -0,0 +1,147 @@
1----------------------------------------------------------------------------
2-- LuaSec 1.3.2
3--
4-- Copyright (C) 2009-2023 PUC-Rio
5--
6-- Author: Pablo Musa
7-- Author: Tomas Guisasola
8---------------------------------------------------------------------------
9
10local socket = require("socket")
11local ssl = require("ssl")
12local ltn12 = require("ltn12")
13local http = require("socket.http")
14local url = require("socket.url")
15
16local try = socket.try
17
18--
19-- Module
20--
21local _M = {
22 _VERSION = "1.3.2",
23 _COPYRIGHT = "LuaSec 1.3.2 - Copyright (C) 2009-2023 PUC-Rio",
24 PORT = 443,
25 TIMEOUT = 60
26}
27
28-- TLS configuration
29local cfg = {
30 protocol = "any",
31 options = {"all", "no_sslv2", "no_sslv3", "no_tlsv1"},
32 verify = "none",
33}
34
35--------------------------------------------------------------------
36-- Auxiliar Functions
37--------------------------------------------------------------------
38
39-- Insert default HTTPS port.
40local function default_https_port(u)
41 return url.build(url.parse(u, {port = _M.PORT}))
42end
43
44-- Convert an URL to a table according to Luasocket needs.
45local function urlstring_totable(url, body, result_table)
46 url = {
47 url = default_https_port(url),
48 method = body and "POST" or "GET",
49 sink = ltn12.sink.table(result_table)
50 }
51 if body then
52 url.source = ltn12.source.string(body)
53 url.headers = {
54 ["content-length"] = #body,
55 ["content-type"] = "application/x-www-form-urlencoded",
56 }
57 end
58 return url
59end
60
61-- Forward calls to the real connection object.
62local function reg(conn)
63 local mt = getmetatable(conn.sock).__index
64 for name, method in pairs(mt) do
65 if type(method) == "function" then
66 conn[name] = function (self, ...)
67 return method(self.sock, ...)
68 end
69 end
70 end
71end
72
73-- Return a function which performs the SSL/TLS connection.
74local function tcp(params)
75 params = params or {}
76 -- Default settings
77 for k, v in pairs(cfg) do
78 params[k] = params[k] or v
79 end
80 -- Force client mode
81 params.mode = "client"
82 -- 'create' function for LuaSocket
83 return function ()
84 local conn = {}
85 conn.sock = try(socket.tcp())
86 local st = getmetatable(conn.sock).__index.settimeout
87 function conn:settimeout(...)
88 return st(self.sock, _M.TIMEOUT)
89 end
90 -- Replace TCP's connection function
91 function conn:connect(host, port)
92 try(self.sock:connect(host, port))
93 self.sock = try(ssl.wrap(self.sock, params))
94 self.sock:sni(host)
95 self.sock:settimeout(_M.TIMEOUT)
96 try(self.sock:dohandshake())
97 reg(self)
98 return 1
99 end
100 return conn
101 end
102end
103
104--------------------------------------------------------------------
105-- Main Function
106--------------------------------------------------------------------
107
108-- Make a HTTP request over secure connection. This function receives
109-- the same parameters of LuaSocket's HTTP module (except 'proxy' and
110-- 'redirect') plus LuaSec parameters.
111--
112-- @param url mandatory (string or table)
113-- @param body optional (string)
114-- @return (string if url == string or 1), code, headers, status
115--
116local function request(url, body)
117 local result_table = {}
118 local stringrequest = type(url) == "string"
119 if stringrequest then
120 url = urlstring_totable(url, body, result_table)
121 else
122 url.url = default_https_port(url.url)
123 end
124 if http.PROXY or url.proxy then
125 return nil, "proxy not supported"
126 elseif url.redirect then
127 return nil, "redirect not supported"
128 elseif url.create then
129 return nil, "create function not permitted"
130 end
131 -- New 'create' function to establish a secure connection
132 url.create = tcp(url)
133 local res, code, headers, status = http.request(url)
134 if res and stringrequest then
135 return table.concat(result_table), code, headers, status
136 end
137 return res, code, headers, status
138end
139
140--------------------------------------------------------------------------------
141-- Export module
142--
143
144_M.request = request
145_M.tcp = tcp
146
147return _M
diff --git a/vendor/luasec/src/luasocket/LICENSE b/vendor/luasec/src/luasocket/LICENSE
new file mode 100644
index 00000000..eadb747b
--- /dev/null
+++ b/vendor/luasec/src/luasocket/LICENSE
@@ -0,0 +1,21 @@
1LuaSocket 3.0-RC1 license
2Copyright (C) 2004-2013 Diego Nehab
3
4Permission is hereby granted, free of charge, to any person obtaining
5a copy of this software and associated documentation files (the
6"Software"), to deal in the Software without restriction, including
7without limitation the rights to use, copy, modify, merge, publish,
8distribute, sublicense, and/or sell copies of the Software, and to
9permit persons to whom the Software is furnished to do so, subject to
10the following conditions:
11
12The above copyright notice and this permission notice shall be
13included in all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/luasec/src/luasocket/Makefile b/vendor/luasec/src/luasocket/Makefile
new file mode 100644
index 00000000..b700fb63
--- /dev/null
+++ b/vendor/luasec/src/luasocket/Makefile
@@ -0,0 +1,26 @@
1OBJS= \
2 io.o \
3 buffer.o \
4 timeout.o \
5 usocket.o
6
7CC ?= cc
8CFLAGS += $(MYCFLAGS) -DLUASOCKET_DEBUG
9AR ?= ar
10RANLIB ?= ranlib
11
12.PHONY: all clean
13
14all: libluasocket.a
15
16libluasocket.a: $(OBJS)
17 $(AR) rcu $@ $(OBJS)
18 $(RANLIB) $@
19
20clean:
21 rm -f $(OBJS) libluasocket.a
22
23buffer.o: buffer.c buffer.h io.h timeout.h
24io.o: io.c io.h timeout.h
25timeout.o: timeout.c timeout.h
26usocket.o: usocket.c socket.h io.h timeout.h usocket.h
diff --git a/vendor/luasec/src/luasocket/buffer.c b/vendor/luasec/src/luasocket/buffer.c
new file mode 100644
index 00000000..0eaac418
--- /dev/null
+++ b/vendor/luasec/src/luasocket/buffer.c
@@ -0,0 +1,278 @@
1/*=========================================================================*\
2* Input/Output interface for Lua programs
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "lua.h"
6#include "lauxlib.h"
7
8#include "buffer.h"
9
10/*=========================================================================*\
11* Internal function prototypes
12\*=========================================================================*/
13static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b);
14static int recvline(p_buffer buf, luaL_Buffer *b);
15static int recvall(p_buffer buf, luaL_Buffer *b);
16static int buffer_get(p_buffer buf, const char **data, size_t *count);
17static void buffer_skip(p_buffer buf, size_t count);
18static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent);
19
20/* min and max macros */
21#ifndef MIN
22#define MIN(x, y) ((x) < (y) ? x : y)
23#endif
24#ifndef MAX
25#define MAX(x, y) ((x) > (y) ? x : y)
26#endif
27
28/*=========================================================================*\
29* Exported functions
30\*=========================================================================*/
31/*-------------------------------------------------------------------------*\
32* Initializes module
33\*-------------------------------------------------------------------------*/
34int buffer_open(lua_State *L) {
35 (void) L;
36 return 0;
37}
38
39/*-------------------------------------------------------------------------*\
40* Initializes C structure
41\*-------------------------------------------------------------------------*/
42void buffer_init(p_buffer buf, p_io io, p_timeout tm) {
43 buf->first = buf->last = 0;
44 buf->io = io;
45 buf->tm = tm;
46 buf->received = buf->sent = 0;
47 buf->birthday = timeout_gettime();
48}
49
50/*-------------------------------------------------------------------------*\
51* object:getstats() interface
52\*-------------------------------------------------------------------------*/
53int buffer_meth_getstats(lua_State *L, p_buffer buf) {
54 lua_pushnumber(L, (lua_Number) buf->received);
55 lua_pushnumber(L, (lua_Number) buf->sent);
56 lua_pushnumber(L, timeout_gettime() - buf->birthday);
57 return 3;
58}
59
60/*-------------------------------------------------------------------------*\
61* object:setstats() interface
62\*-------------------------------------------------------------------------*/
63int buffer_meth_setstats(lua_State *L, p_buffer buf) {
64 buf->received = (long) luaL_optnumber(L, 2, (lua_Number) buf->received);
65 buf->sent = (long) luaL_optnumber(L, 3, (lua_Number) buf->sent);
66 if (lua_isnumber(L, 4)) buf->birthday = timeout_gettime() - lua_tonumber(L, 4);
67 lua_pushnumber(L, 1);
68 return 1;
69}
70
71/*-------------------------------------------------------------------------*\
72* object:send() interface
73\*-------------------------------------------------------------------------*/
74int buffer_meth_send(lua_State *L, p_buffer buf) {
75 int top = lua_gettop(L);
76 int err = IO_DONE;
77 size_t size = 0, sent = 0;
78 const char *data = luaL_checklstring(L, 2, &size);
79 long start = (long) luaL_optnumber(L, 3, 1);
80 long end = (long) luaL_optnumber(L, 4, -1);
81 timeout_markstart(buf->tm);
82 if (start < 0) start = (long) (size+start+1);
83 if (end < 0) end = (long) (size+end+1);
84 if (start < 1) start = (long) 1;
85 if (end > (long) size) end = (long) size;
86 if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent);
87 /* check if there was an error */
88 if (err != IO_DONE) {
89 lua_pushnil(L);
90 lua_pushstring(L, buf->io->error(buf->io->ctx, err));
91 lua_pushnumber(L, (lua_Number) (sent+start-1));
92 } else {
93 lua_pushnumber(L, (lua_Number) (sent+start-1));
94 lua_pushnil(L);
95 lua_pushnil(L);
96 }
97#ifdef LUASOCKET_DEBUG
98 /* push time elapsed during operation as the last return value */
99 lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm));
100#endif
101 return lua_gettop(L) - top;
102}
103
104/*-------------------------------------------------------------------------*\
105* object:receive() interface
106\*-------------------------------------------------------------------------*/
107int buffer_meth_receive(lua_State *L, p_buffer buf) {
108 luaL_Buffer b;
109 size_t size;
110 const char *part;
111 int err = IO_DONE;
112 int top = lua_gettop(L);
113 if (top < 3) {
114 lua_settop(L, 3);
115 top = 3;
116 }
117 part = luaL_optlstring(L, 3, "", &size);
118 timeout_markstart(buf->tm);
119 /* initialize buffer with optional extra prefix
120 * (useful for concatenating previous partial results) */
121 luaL_buffinit(L, &b);
122 luaL_addlstring(&b, part, size);
123 /* receive new patterns */
124 if (!lua_isnumber(L, 2)) {
125 const char *p= luaL_optstring(L, 2, "*l");
126 if (p[0] == '*' && p[1] == 'l') err = recvline(buf, &b);
127 else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b);
128 else luaL_argcheck(L, 0, 2, "invalid receive pattern");
129 /* get a fixed number of bytes (minus what was already partially
130 * received) */
131 } else {
132 double n = lua_tonumber(L, 2);
133 size_t wanted = (size_t) n;
134 luaL_argcheck(L, n >= 0, 2, "invalid receive pattern");
135 if (size == 0 || wanted > size)
136 err = recvraw(buf, wanted-size, &b);
137 }
138 /* check if there was an error */
139 if (err != IO_DONE) {
140 /* we can't push anything in the stack before pushing the
141 * contents of the buffer. this is the reason for the complication */
142 luaL_pushresult(&b);
143 lua_pushstring(L, buf->io->error(buf->io->ctx, err));
144 lua_pushvalue(L, -2);
145 lua_pushnil(L);
146 lua_replace(L, -4);
147 } else {
148 luaL_pushresult(&b);
149 lua_pushnil(L);
150 lua_pushnil(L);
151 }
152#ifdef LUASOCKET_DEBUG
153 /* push time elapsed during operation as the last return value */
154 lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm));
155#endif
156 return lua_gettop(L) - top;
157}
158
159/*-------------------------------------------------------------------------*\
160* Determines if there is any data in the read buffer
161\*-------------------------------------------------------------------------*/
162int buffer_isempty(p_buffer buf) {
163 return buf->first >= buf->last;
164}
165
166/*=========================================================================*\
167* Internal functions
168\*=========================================================================*/
169/*-------------------------------------------------------------------------*\
170* Sends a block of data (unbuffered)
171\*-------------------------------------------------------------------------*/
172#define STEPSIZE 8192
173static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) {
174 p_io io = buf->io;
175 p_timeout tm = buf->tm;
176 size_t total = 0;
177 int err = IO_DONE;
178 while (total < count && err == IO_DONE) {
179 size_t done = 0;
180 size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE;
181 err = io->send(io->ctx, data+total, step, &done, tm);
182 total += done;
183 }
184 *sent = total;
185 buf->sent += total;
186 return err;
187}
188
189/*-------------------------------------------------------------------------*\
190* Reads a fixed number of bytes (buffered)
191\*-------------------------------------------------------------------------*/
192static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) {
193 int err = IO_DONE;
194 size_t total = 0;
195 while (err == IO_DONE) {
196 size_t count; const char *data;
197 err = buffer_get(buf, &data, &count);
198 count = MIN(count, wanted - total);
199 luaL_addlstring(b, data, count);
200 buffer_skip(buf, count);
201 total += count;
202 if (total >= wanted) break;
203 }
204 return err;
205}
206
207/*-------------------------------------------------------------------------*\
208* Reads everything until the connection is closed (buffered)
209\*-------------------------------------------------------------------------*/
210static int recvall(p_buffer buf, luaL_Buffer *b) {
211 int err = IO_DONE;
212 size_t total = 0;
213 while (err == IO_DONE) {
214 const char *data; size_t count;
215 err = buffer_get(buf, &data, &count);
216 total += count;
217 luaL_addlstring(b, data, count);
218 buffer_skip(buf, count);
219 }
220 if (err == IO_CLOSED) {
221 if (total > 0) return IO_DONE;
222 else return IO_CLOSED;
223 } else return err;
224}
225
226/*-------------------------------------------------------------------------*\
227* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF
228* are not returned by the function and are discarded from the buffer
229\*-------------------------------------------------------------------------*/
230static int recvline(p_buffer buf, luaL_Buffer *b) {
231 int err = IO_DONE;
232 while (err == IO_DONE) {
233 size_t count, pos; const char *data;
234 err = buffer_get(buf, &data, &count);
235 pos = 0;
236 while (pos < count && data[pos] != '\n') {
237 /* we ignore all \r's */
238 if (data[pos] != '\r') luaL_addchar(b, data[pos]);
239 pos++;
240 }
241 if (pos < count) { /* found '\n' */
242 buffer_skip(buf, pos+1); /* skip '\n' too */
243 break; /* we are done */
244 } else /* reached the end of the buffer */
245 buffer_skip(buf, pos);
246 }
247 return err;
248}
249
250/*-------------------------------------------------------------------------*\
251* Skips a given number of bytes from read buffer. No data is read from the
252* transport layer
253\*-------------------------------------------------------------------------*/
254static void buffer_skip(p_buffer buf, size_t count) {
255 buf->received += count;
256 buf->first += count;
257 if (buffer_isempty(buf))
258 buf->first = buf->last = 0;
259}
260
261/*-------------------------------------------------------------------------*\
262* Return any data available in buffer, or get more data from transport layer
263* if buffer is empty
264\*-------------------------------------------------------------------------*/
265static int buffer_get(p_buffer buf, const char **data, size_t *count) {
266 int err = IO_DONE;
267 p_io io = buf->io;
268 p_timeout tm = buf->tm;
269 if (buffer_isempty(buf)) {
270 size_t got;
271 err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm);
272 buf->first = 0;
273 buf->last = got;
274 }
275 *count = buf->last - buf->first;
276 *data = buf->data + buf->first;
277 return err;
278}
diff --git a/vendor/luasec/src/luasocket/buffer.h b/vendor/luasec/src/luasocket/buffer.h
new file mode 100644
index 00000000..1281bb39
--- /dev/null
+++ b/vendor/luasec/src/luasocket/buffer.h
@@ -0,0 +1,45 @@
1#ifndef BUF_H
2#define BUF_H
3/*=========================================================================*\
4* Input/Output interface for Lua programs
5* LuaSocket toolkit
6*
7* Line patterns require buffering. Reading one character at a time involves
8* too many system calls and is very slow. This module implements the
9* LuaSocket interface for input/output on connected objects, as seen by
10* Lua programs.
11*
12* Input is buffered. Output is *not* buffered because there was no simple
13* way of making sure the buffered output data would ever be sent.
14*
15* The module is built on top of the I/O abstraction defined in io.h and the
16* timeout management is done with the timeout.h interface.
17\*=========================================================================*/
18#include "lua.h"
19
20#include "io.h"
21#include "timeout.h"
22
23/* buffer size in bytes */
24#define BUF_SIZE 8192
25
26/* buffer control structure */
27typedef struct t_buffer_ {
28 double birthday; /* throttle support info: creation time, */
29 size_t sent, received; /* bytes sent, and bytes received */
30 p_io io; /* IO driver used for this buffer */
31 p_timeout tm; /* timeout management for this buffer */
32 size_t first, last; /* index of first and last bytes of stored data */
33 char data[BUF_SIZE]; /* storage space for buffer data */
34} t_buffer;
35typedef t_buffer *p_buffer;
36
37int buffer_open(lua_State *L);
38void buffer_init(p_buffer buf, p_io io, p_timeout tm);
39int buffer_meth_send(lua_State *L, p_buffer buf);
40int buffer_meth_receive(lua_State *L, p_buffer buf);
41int buffer_meth_getstats(lua_State *L, p_buffer buf);
42int buffer_meth_setstats(lua_State *L, p_buffer buf);
43int buffer_isempty(p_buffer buf);
44
45#endif /* BUF_H */
diff --git a/vendor/luasec/src/luasocket/io.c b/vendor/luasec/src/luasocket/io.c
new file mode 100644
index 00000000..35f46f78
--- /dev/null
+++ b/vendor/luasec/src/luasocket/io.c
@@ -0,0 +1,30 @@
1/*=========================================================================*\
2* Input/Output abstraction
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "io.h"
6
7/*=========================================================================*\
8* Exported functions
9\*=========================================================================*/
10/*-------------------------------------------------------------------------*\
11* Initializes C structure
12\*-------------------------------------------------------------------------*/
13void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx) {
14 io->send = send;
15 io->recv = recv;
16 io->error = error;
17 io->ctx = ctx;
18}
19
20/*-------------------------------------------------------------------------*\
21* I/O error strings
22\*-------------------------------------------------------------------------*/
23const char *io_strerror(int err) {
24 switch (err) {
25 case IO_DONE: return NULL;
26 case IO_CLOSED: return "closed";
27 case IO_TIMEOUT: return "timeout";
28 default: return "unknown error";
29 }
30}
diff --git a/vendor/luasec/src/luasocket/io.h b/vendor/luasec/src/luasocket/io.h
new file mode 100644
index 00000000..8945e2c0
--- /dev/null
+++ b/vendor/luasec/src/luasocket/io.h
@@ -0,0 +1,65 @@
1#ifndef IO_H
2#define IO_H
3/*=========================================================================*\
4* Input/Output abstraction
5* LuaSocket toolkit
6*
7* This module defines the interface that LuaSocket expects from the
8* transport layer for streamed input/output. The idea is that if any
9* transport implements this interface, then the buffer.c functions
10* automatically work on it.
11*
12* The module socket.h implements this interface, and thus the module tcp.h
13* is very simple.
14\*=========================================================================*/
15#include <stdio.h>
16#include "lua.h"
17
18#include "timeout.h"
19
20/* IO error codes */
21enum {
22 IO_DONE = 0, /* operation completed successfully */
23 IO_TIMEOUT = -1, /* operation timed out */
24 IO_CLOSED = -2, /* the connection has been closed */
25 IO_UNKNOWN = -3
26};
27
28/* interface to error message function */
29typedef const char *(*p_error) (
30 void *ctx, /* context needed by send */
31 int err /* error code */
32);
33
34/* interface to send function */
35typedef int (*p_send) (
36 void *ctx, /* context needed by send */
37 const char *data, /* pointer to buffer with data to send */
38 size_t count, /* number of bytes to send from buffer */
39 size_t *sent, /* number of bytes sent uppon return */
40 p_timeout tm /* timeout control */
41);
42
43/* interface to recv function */
44typedef int (*p_recv) (
45 void *ctx, /* context needed by recv */
46 char *data, /* pointer to buffer where data will be written */
47 size_t count, /* number of bytes to receive into buffer */
48 size_t *got, /* number of bytes received uppon return */
49 p_timeout tm /* timeout control */
50);
51
52/* IO driver definition */
53typedef struct t_io_ {
54 void *ctx; /* context needed by send/recv */
55 p_send send; /* send function pointer */
56 p_recv recv; /* receive function pointer */
57 p_error error; /* strerror function */
58} t_io;
59typedef t_io *p_io;
60
61void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx);
62const char *io_strerror(int err);
63
64#endif /* IO_H */
65
diff --git a/vendor/luasec/src/luasocket/socket.h b/vendor/luasec/src/luasocket/socket.h
new file mode 100644
index 00000000..07c20fe3
--- /dev/null
+++ b/vendor/luasec/src/luasocket/socket.h
@@ -0,0 +1,78 @@
1#ifndef SOCKET_H
2#define SOCKET_H
3/*=========================================================================*\
4* Socket compatibilization module
5* LuaSocket toolkit
6*
7* BSD Sockets and WinSock are similar, but there are a few irritating
8* differences. Also, not all *nix platforms behave the same. This module
9* (and the associated usocket.h and wsocket.h) factor these differences and
10* creates a interface compatible with the io.h module.
11\*=========================================================================*/
12#include "io.h"
13
14/*=========================================================================*\
15* Platform specific compatibilization
16\*=========================================================================*/
17#ifdef _WIN32
18#include "wsocket.h"
19#else
20#include "usocket.h"
21#endif
22
23/*=========================================================================*\
24* The connect and accept functions accept a timeout and their
25* implementations are somewhat complicated. We chose to move
26* the timeout control into this module for these functions in
27* order to simplify the modules that use them.
28\*=========================================================================*/
29#include "timeout.h"
30
31/* we are lazy... */
32typedef struct sockaddr SA;
33
34/*=========================================================================*\
35* Functions below implement a comfortable platform independent
36* interface to sockets
37\*=========================================================================*/
38int socket_open(void);
39int socket_close(void);
40void socket_destroy(p_socket ps);
41void socket_shutdown(p_socket ps, int how);
42int socket_sendto(p_socket ps, const char *data, size_t count,
43 size_t *sent, SA *addr, socklen_t addr_len, p_timeout tm);
44int socket_recvfrom(p_socket ps, char *data, size_t count,
45 size_t *got, SA *addr, socklen_t *addr_len, p_timeout tm);
46
47void socket_setnonblocking(p_socket ps);
48void socket_setblocking(p_socket ps);
49
50int socket_waitfd(p_socket ps, int sw, p_timeout tm);
51int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
52 p_timeout tm);
53
54int socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm);
55int socket_create(p_socket ps, int domain, int type, int protocol);
56int socket_bind(p_socket ps, SA *addr, socklen_t addr_len);
57int socket_listen(p_socket ps, int backlog);
58int socket_accept(p_socket ps, p_socket pa, SA *addr,
59 socklen_t *addr_len, p_timeout tm);
60
61const char *socket_hoststrerror(int err);
62const char *socket_gaistrerror(int err);
63const char *socket_strerror(int err);
64
65/* these are perfect to use with the io abstraction module
66 and the buffered input module */
67int socket_send(p_socket ps, const char *data, size_t count,
68 size_t *sent, p_timeout tm);
69int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm);
70int socket_write(p_socket ps, const char *data, size_t count,
71 size_t *sent, p_timeout tm);
72int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm);
73const char *socket_ioerror(p_socket ps, int err);
74
75int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp);
76int socket_gethostbyname(const char *addr, struct hostent **hp);
77
78#endif /* SOCKET_H */
diff --git a/vendor/luasec/src/luasocket/timeout.c b/vendor/luasec/src/luasocket/timeout.c
new file mode 100644
index 00000000..94a524be
--- /dev/null
+++ b/vendor/luasec/src/luasocket/timeout.c
@@ -0,0 +1,220 @@
1/*=========================================================================*\
2* Timeout management functions
3* LuaSocket toolkit
4\*=========================================================================*/
5#include <stdio.h>
6#include <limits.h>
7#include <float.h>
8
9#include "lua.h"
10#include "lauxlib.h"
11
12#include "timeout.h"
13
14#ifdef _WIN32
15#include <windows.h>
16#else
17#include <time.h>
18#include <sys/time.h>
19#endif
20
21/* min and max macros */
22#ifndef MIN
23#define MIN(x, y) ((x) < (y) ? x : y)
24#endif
25#ifndef MAX
26#define MAX(x, y) ((x) > (y) ? x : y)
27#endif
28
29/*=========================================================================*\
30* Internal function prototypes
31\*=========================================================================*/
32static int timeout_lua_gettime(lua_State *L);
33static int timeout_lua_sleep(lua_State *L);
34
35static luaL_Reg func[] = {
36 { "gettime", timeout_lua_gettime },
37 { "sleep", timeout_lua_sleep },
38 { NULL, NULL }
39};
40
41/*=========================================================================*\
42* Exported functions.
43\*=========================================================================*/
44/*-------------------------------------------------------------------------*\
45* Initialize structure
46\*-------------------------------------------------------------------------*/
47void timeout_init(p_timeout tm, double block, double total) {
48 tm->block = block;
49 tm->total = total;
50}
51
52/*-------------------------------------------------------------------------*\
53* Determines how much time we have left for the next system call,
54* if the previous call was successful
55* Input
56* tm: timeout control structure
57* Returns
58* the number of ms left or -1 if there is no time limit
59\*-------------------------------------------------------------------------*/
60double timeout_get(p_timeout tm) {
61 if (tm->block < 0.0 && tm->total < 0.0) {
62 return -1;
63 } else if (tm->block < 0.0) {
64 double t = tm->total - timeout_gettime() + tm->start;
65 return MAX(t, 0.0);
66 } else if (tm->total < 0.0) {
67 return tm->block;
68 } else {
69 double t = tm->total - timeout_gettime() + tm->start;
70 return MIN(tm->block, MAX(t, 0.0));
71 }
72}
73
74/*-------------------------------------------------------------------------*\
75* Returns time since start of operation
76* Input
77* tm: timeout control structure
78* Returns
79* start field of structure
80\*-------------------------------------------------------------------------*/
81double timeout_getstart(p_timeout tm) {
82 return tm->start;
83}
84
85/*-------------------------------------------------------------------------*\
86* Determines how much time we have left for the next system call,
87* if the previous call was a failure
88* Input
89* tm: timeout control structure
90* Returns
91* the number of ms left or -1 if there is no time limit
92\*-------------------------------------------------------------------------*/
93double timeout_getretry(p_timeout tm) {
94 if (tm->block < 0.0 && tm->total < 0.0) {
95 return -1;
96 } else if (tm->block < 0.0) {
97 double t = tm->total - timeout_gettime() + tm->start;
98 return MAX(t, 0.0);
99 } else if (tm->total < 0.0) {
100 double t = tm->block - timeout_gettime() + tm->start;
101 return MAX(t, 0.0);
102 } else {
103 double t = tm->total - timeout_gettime() + tm->start;
104 return MIN(tm->block, MAX(t, 0.0));
105 }
106}
107
108/*-------------------------------------------------------------------------*\
109* Marks the operation start time in structure
110* Input
111* tm: timeout control structure
112\*-------------------------------------------------------------------------*/
113p_timeout timeout_markstart(p_timeout tm) {
114 tm->start = timeout_gettime();
115 return tm;
116}
117
118/*-------------------------------------------------------------------------*\
119* Gets time in s, relative to January 1, 1970 (UTC)
120* Returns
121* time in s.
122\*-------------------------------------------------------------------------*/
123#ifdef _WIN32
124double timeout_gettime(void) {
125 FILETIME ft;
126 double t;
127 GetSystemTimeAsFileTime(&ft);
128 /* Windows file time (time since January 1, 1601 (UTC)) */
129 t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
130 /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
131 return (t - 11644473600.0);
132}
133#else
134double timeout_gettime(void) {
135 struct timeval v;
136 gettimeofday(&v, (struct timezone *) NULL);
137 /* Unix Epoch time (time since January 1, 1970 (UTC)) */
138 return v.tv_sec + v.tv_usec/1.0e6;
139}
140#endif
141
142/*-------------------------------------------------------------------------*\
143* Initializes module
144\*-------------------------------------------------------------------------*/
145int timeout_open(lua_State *L) {
146#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
147 luaL_setfuncs(L, func, 0);
148#else
149 luaL_openlib(L, NULL, func, 0);
150#endif
151 return 0;
152}
153
154/*-------------------------------------------------------------------------*\
155* Sets timeout values for IO operations
156* Lua Input: base, time [, mode]
157* time: time out value in seconds
158* mode: "b" for block timeout, "t" for total timeout. (default: b)
159\*-------------------------------------------------------------------------*/
160int timeout_meth_settimeout(lua_State *L, p_timeout tm) {
161 double t = luaL_optnumber(L, 2, -1);
162 const char *mode = luaL_optstring(L, 3, "b");
163 switch (*mode) {
164 case 'b':
165 tm->block = t;
166 break;
167 case 'r': case 't':
168 tm->total = t;
169 break;
170 default:
171 luaL_argcheck(L, 0, 3, "invalid timeout mode");
172 break;
173 }
174 lua_pushnumber(L, 1);
175 return 1;
176}
177
178/*=========================================================================*\
179* Test support functions
180\*=========================================================================*/
181/*-------------------------------------------------------------------------*\
182* Returns the time the system has been up, in secconds.
183\*-------------------------------------------------------------------------*/
184static int timeout_lua_gettime(lua_State *L)
185{
186 lua_pushnumber(L, timeout_gettime());
187 return 1;
188}
189
190/*-------------------------------------------------------------------------*\
191* Sleep for n seconds.
192\*-------------------------------------------------------------------------*/
193#ifdef _WIN32
194int timeout_lua_sleep(lua_State *L)
195{
196 double n = luaL_checknumber(L, 1);
197 if (n < 0.0) n = 0.0;
198 if (n < DBL_MAX/1000.0) n *= 1000.0;
199 if (n > INT_MAX) n = INT_MAX;
200 Sleep((int)n);
201 return 0;
202}
203#else
204int timeout_lua_sleep(lua_State *L)
205{
206 double n = luaL_checknumber(L, 1);
207 struct timespec t, r;
208 if (n < 0.0) n = 0.0;
209 if (n > INT_MAX) n = INT_MAX;
210 t.tv_sec = (int) n;
211 n -= t.tv_sec;
212 t.tv_nsec = (int) (n * 1000000000);
213 if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999;
214 while (nanosleep(&t, &r) != 0) {
215 t.tv_sec = r.tv_sec;
216 t.tv_nsec = r.tv_nsec;
217 }
218 return 0;
219}
220#endif
diff --git a/vendor/luasec/src/luasocket/timeout.h b/vendor/luasec/src/luasocket/timeout.h
new file mode 100644
index 00000000..4957593b
--- /dev/null
+++ b/vendor/luasec/src/luasocket/timeout.h
@@ -0,0 +1,28 @@
1#ifndef TIMEOUT_H
2#define TIMEOUT_H
3/*=========================================================================*\
4* Timeout management functions
5* LuaSocket toolkit
6\*=========================================================================*/
7#include "lua.h"
8
9/* timeout control structure */
10typedef struct t_timeout_ {
11 double block; /* maximum time for blocking calls */
12 double total; /* total number of milliseconds for operation */
13 double start; /* time of start of operation */
14} t_timeout;
15typedef t_timeout *p_timeout;
16
17int timeout_open(lua_State *L);
18void timeout_init(p_timeout tm, double block, double total);
19double timeout_get(p_timeout tm);
20double timeout_getretry(p_timeout tm);
21p_timeout timeout_markstart(p_timeout tm);
22double timeout_getstart(p_timeout tm);
23double timeout_gettime(void);
24int timeout_meth_settimeout(lua_State *L, p_timeout tm);
25
26#define timeout_iszero(tm) ((tm)->block == 0.0)
27
28#endif /* TIMEOUT_H */
diff --git a/vendor/luasec/src/luasocket/usocket.c b/vendor/luasec/src/luasocket/usocket.c
new file mode 100644
index 00000000..49e618c4
--- /dev/null
+++ b/vendor/luasec/src/luasocket/usocket.c
@@ -0,0 +1,441 @@
1/*=========================================================================*\
2* Socket compatibilization module for Unix
3* LuaSocket toolkit
4*
5* The code is now interrupt-safe.
6* The penalty of calling select to avoid busy-wait is only paid when
7* the I/O call fail in the first place.
8\*=========================================================================*/
9#include <string.h>
10#include <signal.h>
11
12#include "socket.h"
13
14/*-------------------------------------------------------------------------*\
15* Wait for readable/writable/connected socket with timeout
16\*-------------------------------------------------------------------------*/
17#ifndef SOCKET_SELECT
18int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
19 int ret;
20 struct pollfd pfd;
21 pfd.fd = *ps;
22 pfd.events = sw;
23 pfd.revents = 0;
24 if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
25 do {
26 int t = (int)(timeout_getretry(tm)*1e3);
27 ret = poll(&pfd, 1, t >= 0? t: -1);
28 } while (ret == -1 && errno == EINTR);
29 if (ret == -1) return errno;
30 if (ret == 0) return IO_TIMEOUT;
31 if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED;
32 return IO_DONE;
33}
34#else
35int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
36 int ret;
37 fd_set rfds, wfds, *rp, *wp;
38 struct timeval tv, *tp;
39 double t;
40 if (*ps >= FD_SETSIZE) return EINVAL;
41 if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
42 do {
43 /* must set bits within loop, because select may have modified them */
44 rp = wp = NULL;
45 if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; }
46 if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
47 t = timeout_getretry(tm);
48 tp = NULL;
49 if (t >= 0.0) {
50 tv.tv_sec = (int)t;
51 tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6);
52 tp = &tv;
53 }
54 ret = select(*ps+1, rp, wp, NULL, tp);
55 } while (ret == -1 && errno == EINTR);
56 if (ret == -1) return errno;
57 if (ret == 0) return IO_TIMEOUT;
58 if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED;
59 return IO_DONE;
60}
61#endif
62
63
64/*-------------------------------------------------------------------------*\
65* Initializes module
66\*-------------------------------------------------------------------------*/
67int socket_open(void) {
68 /* instals a handler to ignore sigpipe or it will crash us */
69 signal(SIGPIPE, SIG_IGN);
70 return 1;
71}
72
73/*-------------------------------------------------------------------------*\
74* Close module
75\*-------------------------------------------------------------------------*/
76int socket_close(void) {
77 return 1;
78}
79
80/*-------------------------------------------------------------------------*\
81* Close and inutilize socket
82\*-------------------------------------------------------------------------*/
83void socket_destroy(p_socket ps) {
84 if (*ps != SOCKET_INVALID) {
85 socket_setblocking(ps);
86 close(*ps);
87 *ps = SOCKET_INVALID;
88 }
89}
90
91/*-------------------------------------------------------------------------*\
92* Select with timeout control
93\*-------------------------------------------------------------------------*/
94int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
95 p_timeout tm) {
96 int ret;
97 do {
98 struct timeval tv;
99 double t = timeout_getretry(tm);
100 tv.tv_sec = (int) t;
101 tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
102 /* timeout = 0 means no wait */
103 ret = select(n, rfds, wfds, efds, t >= 0.0 ? &tv: NULL);
104 } while (ret < 0 && errno == EINTR);
105 return ret;
106}
107
108/*-------------------------------------------------------------------------*\
109* Creates and sets up a socket
110\*-------------------------------------------------------------------------*/
111int socket_create(p_socket ps, int domain, int type, int protocol) {
112 *ps = socket(domain, type, protocol);
113 if (*ps != SOCKET_INVALID) return IO_DONE;
114 else return errno;
115}
116
117/*-------------------------------------------------------------------------*\
118* Binds or returns error message
119\*-------------------------------------------------------------------------*/
120int socket_bind(p_socket ps, SA *addr, socklen_t len) {
121 int err = IO_DONE;
122 socket_setblocking(ps);
123 if (bind(*ps, addr, len) < 0) err = errno;
124 socket_setnonblocking(ps);
125 return err;
126}
127
128/*-------------------------------------------------------------------------*\
129*
130\*-------------------------------------------------------------------------*/
131int socket_listen(p_socket ps, int backlog) {
132 int err = IO_DONE;
133 socket_setblocking(ps);
134 if (listen(*ps, backlog)) err = errno;
135 socket_setnonblocking(ps);
136 return err;
137}
138
139/*-------------------------------------------------------------------------*\
140*
141\*-------------------------------------------------------------------------*/
142void socket_shutdown(p_socket ps, int how) {
143 socket_setblocking(ps);
144 shutdown(*ps, how);
145 socket_setnonblocking(ps);
146}
147
148/*-------------------------------------------------------------------------*\
149* Connects or returns error message
150\*-------------------------------------------------------------------------*/
151int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
152 int err;
153 /* avoid calling on closed sockets */
154 if (*ps == SOCKET_INVALID) return IO_CLOSED;
155 /* call connect until done or failed without being interrupted */
156 do if (connect(*ps, addr, len) == 0) return IO_DONE;
157 while ((err = errno) == EINTR);
158 /* if connection failed immediately, return error code */
159 if (err != EINPROGRESS && err != EAGAIN) return err;
160 /* zero timeout case optimization */
161 if (timeout_iszero(tm)) return IO_TIMEOUT;
162 /* wait until we have the result of the connection attempt or timeout */
163 err = socket_waitfd(ps, WAITFD_C, tm);
164 if (err == IO_CLOSED) {
165 if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE;
166 else return errno;
167 } else return err;
168}
169
170/*-------------------------------------------------------------------------*\
171* Accept with timeout
172\*-------------------------------------------------------------------------*/
173int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) {
174 if (*ps == SOCKET_INVALID) return IO_CLOSED;
175 for ( ;; ) {
176 int err;
177 if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
178 err = errno;
179 if (err == EINTR) continue;
180 if (err != EAGAIN && err != ECONNABORTED) return err;
181 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
182 }
183 /* can't reach here */
184 return IO_UNKNOWN;
185}
186
187/*-------------------------------------------------------------------------*\
188* Send with timeout
189\*-------------------------------------------------------------------------*/
190int socket_send(p_socket ps, const char *data, size_t count,
191 size_t *sent, p_timeout tm)
192{
193 int err;
194 *sent = 0;
195 /* avoid making system calls on closed sockets */
196 if (*ps == SOCKET_INVALID) return IO_CLOSED;
197 /* loop until we send something or we give up on error */
198 for ( ;; ) {
199 long put = (long) send(*ps, data, count, 0);
200 /* if we sent anything, we are done */
201 if (put >= 0) {
202 *sent = put;
203 return IO_DONE;
204 }
205 err = errno;
206 /* EPIPE means the connection was closed */
207 if (err == EPIPE) return IO_CLOSED;
208 /* we call was interrupted, just try again */
209 if (err == EINTR) continue;
210 /* if failed fatal reason, report error */
211 if (err != EAGAIN) return err;
212 /* wait until we can send something or we timeout */
213 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
214 }
215 /* can't reach here */
216 return IO_UNKNOWN;
217}
218
219/*-------------------------------------------------------------------------*\
220* Sendto with timeout
221\*-------------------------------------------------------------------------*/
222int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
223 SA *addr, socklen_t len, p_timeout tm)
224{
225 int err;
226 *sent = 0;
227 if (*ps == SOCKET_INVALID) return IO_CLOSED;
228 for ( ;; ) {
229 long put = (long) sendto(*ps, data, count, 0, addr, len);
230 if (put >= 0) {
231 *sent = put;
232 return IO_DONE;
233 }
234 err = errno;
235 if (err == EPIPE) return IO_CLOSED;
236 if (err == EINTR) continue;
237 if (err != EAGAIN) return err;
238 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
239 }
240 return IO_UNKNOWN;
241}
242
243/*-------------------------------------------------------------------------*\
244* Receive with timeout
245\*-------------------------------------------------------------------------*/
246int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) {
247 int err;
248 *got = 0;
249 if (*ps == SOCKET_INVALID) return IO_CLOSED;
250 for ( ;; ) {
251 long taken = (long) recv(*ps, data, count, 0);
252 if (taken > 0) {
253 *got = taken;
254 return IO_DONE;
255 }
256 err = errno;
257 if (taken == 0) return IO_CLOSED;
258 if (err == EINTR) continue;
259 if (err != EAGAIN) return err;
260 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
261 }
262 return IO_UNKNOWN;
263}
264
265/*-------------------------------------------------------------------------*\
266* Recvfrom with timeout
267\*-------------------------------------------------------------------------*/
268int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
269 SA *addr, socklen_t *len, p_timeout tm) {
270 int err;
271 *got = 0;
272 if (*ps == SOCKET_INVALID) return IO_CLOSED;
273 for ( ;; ) {
274 long taken = (long) recvfrom(*ps, data, count, 0, addr, len);
275 if (taken > 0) {
276 *got = taken;
277 return IO_DONE;
278 }
279 err = errno;
280 if (taken == 0) return IO_CLOSED;
281 if (err == EINTR) continue;
282 if (err != EAGAIN) return err;
283 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
284 }
285 return IO_UNKNOWN;
286}
287
288
289/*-------------------------------------------------------------------------*\
290* Write with timeout
291*
292* socket_read and socket_write are cut-n-paste of socket_send and socket_recv,
293* with send/recv replaced with write/read. We can't just use write/read
294* in the socket version, because behaviour when size is zero is different.
295\*-------------------------------------------------------------------------*/
296int socket_write(p_socket ps, const char *data, size_t count,
297 size_t *sent, p_timeout tm)
298{
299 int err;
300 *sent = 0;
301 /* avoid making system calls on closed sockets */
302 if (*ps == SOCKET_INVALID) return IO_CLOSED;
303 /* loop until we send something or we give up on error */
304 for ( ;; ) {
305 long put = (long) write(*ps, data, count);
306 /* if we sent anything, we are done */
307 if (put >= 0) {
308 *sent = put;
309 return IO_DONE;
310 }
311 err = errno;
312 /* EPIPE means the connection was closed */
313 if (err == EPIPE) return IO_CLOSED;
314 /* we call was interrupted, just try again */
315 if (err == EINTR) continue;
316 /* if failed fatal reason, report error */
317 if (err != EAGAIN) return err;
318 /* wait until we can send something or we timeout */
319 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
320 }
321 /* can't reach here */
322 return IO_UNKNOWN;
323}
324
325/*-------------------------------------------------------------------------*\
326* Read with timeout
327* See note for socket_write
328\*-------------------------------------------------------------------------*/
329int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) {
330 int err;
331 *got = 0;
332 if (*ps == SOCKET_INVALID) return IO_CLOSED;
333 for ( ;; ) {
334 long taken = (long) read(*ps, data, count);
335 if (taken > 0) {
336 *got = taken;
337 return IO_DONE;
338 }
339 err = errno;
340 if (taken == 0) return IO_CLOSED;
341 if (err == EINTR) continue;
342 if (err != EAGAIN) return err;
343 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
344 }
345 return IO_UNKNOWN;
346}
347
348/*-------------------------------------------------------------------------*\
349* Put socket into blocking mode
350\*-------------------------------------------------------------------------*/
351void socket_setblocking(p_socket ps) {
352 int flags = fcntl(*ps, F_GETFL, 0);
353 flags &= (~(O_NONBLOCK));
354 fcntl(*ps, F_SETFL, flags);
355}
356
357/*-------------------------------------------------------------------------*\
358* Put socket into non-blocking mode
359\*-------------------------------------------------------------------------*/
360void socket_setnonblocking(p_socket ps) {
361 int flags = fcntl(*ps, F_GETFL, 0);
362 flags |= O_NONBLOCK;
363 fcntl(*ps, F_SETFL, flags);
364}
365
366/*-------------------------------------------------------------------------*\
367* DNS helpers
368\*-------------------------------------------------------------------------*/
369int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
370 *hp = gethostbyaddr(addr, len, AF_INET);
371 if (*hp) return IO_DONE;
372 else if (h_errno) return h_errno;
373 else if (errno) return errno;
374 else return IO_UNKNOWN;
375}
376
377int socket_gethostbyname(const char *addr, struct hostent **hp) {
378 *hp = gethostbyname(addr);
379 if (*hp) return IO_DONE;
380 else if (h_errno) return h_errno;
381 else if (errno) return errno;
382 else return IO_UNKNOWN;
383}
384
385/*-------------------------------------------------------------------------*\
386* Error translation functions
387* Make sure important error messages are standard
388\*-------------------------------------------------------------------------*/
389const char *socket_hoststrerror(int err) {
390 if (err <= 0) return io_strerror(err);
391 switch (err) {
392 case HOST_NOT_FOUND: return "host not found";
393 default: return hstrerror(err);
394 }
395}
396
397const char *socket_strerror(int err) {
398 if (err <= 0) return io_strerror(err);
399 switch (err) {
400 case EADDRINUSE: return "address already in use";
401 case EISCONN: return "already connected";
402 case EACCES: return "permission denied";
403 case ECONNREFUSED: return "connection refused";
404 case ECONNABORTED: return "closed";
405 case ECONNRESET: return "closed";
406 case ETIMEDOUT: return "timeout";
407 default: return strerror(err);
408 }
409}
410
411const char *socket_ioerror(p_socket ps, int err) {
412 (void) ps;
413 return socket_strerror(err);
414}
415
416const char *socket_gaistrerror(int err) {
417 if (err == 0) return NULL;
418 switch (err) {
419 case EAI_AGAIN: return "temporary failure in name resolution";
420 case EAI_BADFLAGS: return "invalid value for ai_flags";
421#ifdef EAI_BADHINTS
422 case EAI_BADHINTS: return "invalid value for hints";
423#endif
424 case EAI_FAIL: return "non-recoverable failure in name resolution";
425 case EAI_FAMILY: return "ai_family not supported";
426 case EAI_MEMORY: return "memory allocation failure";
427 case EAI_NONAME:
428 return "host or service not provided, or not known";
429#ifdef EAI_OVERFLOW
430 case EAI_OVERFLOW: return "argument buffer overflow";
431#endif
432#ifdef EAI_PROTOCOL
433 case EAI_PROTOCOL: return "resolved protocol is unknown";
434#endif
435 case EAI_SERVICE: return "service not supported for socket type";
436 case EAI_SOCKTYPE: return "ai_socktype not supported";
437 case EAI_SYSTEM: return strerror(errno);
438 default: return gai_strerror(err);
439 }
440}
441
diff --git a/vendor/luasec/src/luasocket/usocket.h b/vendor/luasec/src/luasocket/usocket.h
new file mode 100644
index 00000000..ecbcd8e5
--- /dev/null
+++ b/vendor/luasec/src/luasocket/usocket.h
@@ -0,0 +1,70 @@
1#ifndef USOCKET_H
2#define USOCKET_H
3/*=========================================================================*\
4* Socket compatibilization module for Unix
5* LuaSocket toolkit
6\*=========================================================================*/
7
8/*=========================================================================*\
9* BSD include files
10\*=========================================================================*/
11/* error codes */
12#include <errno.h>
13/* close function */
14#include <unistd.h>
15/* fnctnl function and associated constants */
16#include <fcntl.h>
17/* struct sockaddr */
18#include <sys/types.h>
19/* socket function */
20#include <sys/socket.h>
21/* struct timeval */
22#include <sys/time.h>
23/* gethostbyname and gethostbyaddr functions */
24#include <netdb.h>
25/* sigpipe handling */
26#include <signal.h>
27/* IP stuff*/
28#include <netinet/in.h>
29#include <arpa/inet.h>
30/* TCP options (nagle algorithm disable) */
31#include <netinet/tcp.h>
32#include <net/if.h>
33
34#ifndef SOCKET_SELECT
35#include <sys/poll.h>
36#define WAITFD_R POLLIN
37#define WAITFD_W POLLOUT
38#define WAITFD_C (POLLIN|POLLOUT)
39#else
40#define WAITFD_R 1
41#define WAITFD_W 2
42#define WAITFD_C (WAITFD_R|WAITFD_W)
43#endif
44
45#ifndef SO_REUSEPORT
46#define SO_REUSEPORT SO_REUSEADDR
47#endif
48
49/* Some platforms use IPV6_JOIN_GROUP instead if
50 * IPV6_ADD_MEMBERSHIP. The semantics are same, though. */
51#ifndef IPV6_ADD_MEMBERSHIP
52#ifdef IPV6_JOIN_GROUP
53#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
54#endif /* IPV6_JOIN_GROUP */
55#endif /* !IPV6_ADD_MEMBERSHIP */
56
57/* Same with IPV6_DROP_MEMBERSHIP / IPV6_LEAVE_GROUP. */
58#ifndef IPV6_DROP_MEMBERSHIP
59#ifdef IPV6_LEAVE_GROUP
60#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
61#endif /* IPV6_LEAVE_GROUP */
62#endif /* !IPV6_DROP_MEMBERSHIP */
63
64typedef int t_socket;
65typedef t_socket *p_socket;
66typedef struct sockaddr_storage t_sockaddr_storage;
67
68#define SOCKET_INVALID (-1)
69
70#endif /* USOCKET_H */
diff --git a/vendor/luasec/src/luasocket/wsocket.c b/vendor/luasec/src/luasocket/wsocket.c
new file mode 100644
index 00000000..8c7640eb
--- /dev/null
+++ b/vendor/luasec/src/luasocket/wsocket.c
@@ -0,0 +1,429 @@
1/*=========================================================================*\
2* Socket compatibilization module for Win32
3* LuaSocket toolkit
4*
5* The penalty of calling select to avoid busy-wait is only paid when
6* the I/O call fail in the first place.
7\*=========================================================================*/
8#include <string.h>
9
10#include "socket.h"
11
12/* WinSock doesn't have a strerror... */
13static const char *wstrerror(int err);
14
15/*-------------------------------------------------------------------------*\
16* Initializes module
17\*-------------------------------------------------------------------------*/
18int socket_open(void) {
19 WSADATA wsaData;
20 WORD wVersionRequested = MAKEWORD(2, 0);
21 int err = WSAStartup(wVersionRequested, &wsaData );
22 if (err != 0) return 0;
23 if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) &&
24 (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) {
25 WSACleanup();
26 return 0;
27 }
28 return 1;
29}
30
31/*-------------------------------------------------------------------------*\
32* Close module
33\*-------------------------------------------------------------------------*/
34int socket_close(void) {
35 WSACleanup();
36 return 1;
37}
38
39/*-------------------------------------------------------------------------*\
40* Wait for readable/writable/connected socket with timeout
41\*-------------------------------------------------------------------------*/
42int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
43 int ret;
44 fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL;
45 struct timeval tv, *tp = NULL;
46 double t;
47 if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
48 if (sw & WAITFD_R) {
49 FD_ZERO(&rfds);
50 FD_SET(*ps, &rfds);
51 rp = &rfds;
52 }
53 if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
54 if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
55 if ((t = timeout_get(tm)) >= 0.0) {
56 tv.tv_sec = (int) t;
57 tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6);
58 tp = &tv;
59 }
60 ret = select(0, rp, wp, ep, tp);
61 if (ret == -1) return WSAGetLastError();
62 if (ret == 0) return IO_TIMEOUT;
63 if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED;
64 return IO_DONE;
65}
66
67/*-------------------------------------------------------------------------*\
68* Select with int timeout in ms
69\*-------------------------------------------------------------------------*/
70int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
71 p_timeout tm) {
72 struct timeval tv;
73 double t = timeout_get(tm);
74 tv.tv_sec = (int) t;
75 tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
76 if (n <= 0) {
77 Sleep((DWORD) (1000*t));
78 return 0;
79 } else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
80}
81
82/*-------------------------------------------------------------------------*\
83* Close and inutilize socket
84\*-------------------------------------------------------------------------*/
85void socket_destroy(p_socket ps) {
86 if (*ps != SOCKET_INVALID) {
87 socket_setblocking(ps); /* close can take a long time on WIN32 */
88 closesocket(*ps);
89 *ps = SOCKET_INVALID;
90 }
91}
92
93/*-------------------------------------------------------------------------*\
94*
95\*-------------------------------------------------------------------------*/
96void socket_shutdown(p_socket ps, int how) {
97 socket_setblocking(ps);
98 shutdown(*ps, how);
99 socket_setnonblocking(ps);
100}
101
102/*-------------------------------------------------------------------------*\
103* Creates and sets up a socket
104\*-------------------------------------------------------------------------*/
105int socket_create(p_socket ps, int domain, int type, int protocol) {
106 *ps = socket(domain, type, protocol);
107 if (*ps != SOCKET_INVALID) return IO_DONE;
108 else return WSAGetLastError();
109}
110
111/*-------------------------------------------------------------------------*\
112* Connects or returns error message
113\*-------------------------------------------------------------------------*/
114int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
115 int err;
116 /* don't call on closed socket */
117 if (*ps == SOCKET_INVALID) return IO_CLOSED;
118 /* ask system to connect */
119 if (connect(*ps, addr, len) == 0) return IO_DONE;
120 /* make sure the system is trying to connect */
121 err = WSAGetLastError();
122 if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err;
123 /* zero timeout case optimization */
124 if (timeout_iszero(tm)) return IO_TIMEOUT;
125 /* we wait until something happens */
126 err = socket_waitfd(ps, WAITFD_C, tm);
127 if (err == IO_CLOSED) {
128 int len = sizeof(err);
129 /* give windows time to set the error (yes, disgusting) */
130 Sleep(10);
131 /* find out why we failed */
132 getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
133 /* we KNOW there was an error. if 'why' is 0, we will return
134 * "unknown error", but it's not really our fault */
135 return err > 0? err: IO_UNKNOWN;
136 } else return err;
137
138}
139
140/*-------------------------------------------------------------------------*\
141* Binds or returns error message
142\*-------------------------------------------------------------------------*/
143int socket_bind(p_socket ps, SA *addr, socklen_t len) {
144 int err = IO_DONE;
145 socket_setblocking(ps);
146 if (bind(*ps, addr, len) < 0) err = WSAGetLastError();
147 socket_setnonblocking(ps);
148 return err;
149}
150
151/*-------------------------------------------------------------------------*\
152*
153\*-------------------------------------------------------------------------*/
154int socket_listen(p_socket ps, int backlog) {
155 int err = IO_DONE;
156 socket_setblocking(ps);
157 if (listen(*ps, backlog) < 0) err = WSAGetLastError();
158 socket_setnonblocking(ps);
159 return err;
160}
161
162/*-------------------------------------------------------------------------*\
163* Accept with timeout
164\*-------------------------------------------------------------------------*/
165int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,
166 p_timeout tm) {
167 if (*ps == SOCKET_INVALID) return IO_CLOSED;
168 for ( ;; ) {
169 int err;
170 /* try to get client socket */
171 if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
172 /* find out why we failed */
173 err = WSAGetLastError();
174 /* if we failed because there was no connectoin, keep trying */
175 if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err;
176 /* call select to avoid busy wait */
177 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
178 }
179}
180
181/*-------------------------------------------------------------------------*\
182* Send with timeout
183* On windows, if you try to send 10MB, the OS will buffer EVERYTHING
184* this can take an awful lot of time and we will end up blocked.
185* Therefore, whoever calls this function should not pass a huge buffer.
186\*-------------------------------------------------------------------------*/
187int socket_send(p_socket ps, const char *data, size_t count,
188 size_t *sent, p_timeout tm)
189{
190 int err;
191 *sent = 0;
192 /* avoid making system calls on closed sockets */
193 if (*ps == SOCKET_INVALID) return IO_CLOSED;
194 /* loop until we send something or we give up on error */
195 for ( ;; ) {
196 /* try to send something */
197 int put = send(*ps, data, (int) count, 0);
198 /* if we sent something, we are done */
199 if (put > 0) {
200 *sent = put;
201 return IO_DONE;
202 }
203 /* deal with failure */
204 err = WSAGetLastError();
205 /* we can only proceed if there was no serious error */
206 if (err != WSAEWOULDBLOCK) return err;
207 /* avoid busy wait */
208 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
209 }
210}
211
212/*-------------------------------------------------------------------------*\
213* Sendto with timeout
214\*-------------------------------------------------------------------------*/
215int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
216 SA *addr, socklen_t len, p_timeout tm)
217{
218 int err;
219 *sent = 0;
220 if (*ps == SOCKET_INVALID) return IO_CLOSED;
221 for ( ;; ) {
222 int put = sendto(*ps, data, (int) count, 0, addr, len);
223 if (put > 0) {
224 *sent = put;
225 return IO_DONE;
226 }
227 err = WSAGetLastError();
228 if (err != WSAEWOULDBLOCK) return err;
229 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
230 }
231}
232
233/*-------------------------------------------------------------------------*\
234* Receive with timeout
235\*-------------------------------------------------------------------------*/
236int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
237 p_timeout tm)
238{
239 int err, prev = IO_DONE;
240 *got = 0;
241 if (*ps == SOCKET_INVALID) return IO_CLOSED;
242 for ( ;; ) {
243 int taken = recv(*ps, data, (int) count, 0);
244 if (taken > 0) {
245 *got = taken;
246 return IO_DONE;
247 }
248 if (taken == 0) return IO_CLOSED;
249 err = WSAGetLastError();
250 /* On UDP, a connreset simply means the previous send failed.
251 * So we try again.
252 * On TCP, it means our socket is now useless, so the error passes.
253 * (We will loop again, exiting because the same error will happen) */
254 if (err != WSAEWOULDBLOCK) {
255 if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
256 prev = err;
257 }
258 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
259 }
260}
261
262/*-------------------------------------------------------------------------*\
263* Recvfrom with timeout
264\*-------------------------------------------------------------------------*/
265int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
266 SA *addr, socklen_t *len, p_timeout tm)
267{
268 int err, prev = IO_DONE;
269 *got = 0;
270 if (*ps == SOCKET_INVALID) return IO_CLOSED;
271 for ( ;; ) {
272 int taken = recvfrom(*ps, data, (int) count, 0, addr, len);
273 if (taken > 0) {
274 *got = taken;
275 return IO_DONE;
276 }
277 if (taken == 0) return IO_CLOSED;
278 err = WSAGetLastError();
279 /* On UDP, a connreset simply means the previous send failed.
280 * So we try again.
281 * On TCP, it means our socket is now useless, so the error passes.
282 * (We will loop again, exiting because the same error will happen) */
283 if (err != WSAEWOULDBLOCK) {
284 if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
285 prev = err;
286 }
287 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
288 }
289}
290
291/*-------------------------------------------------------------------------*\
292* Put socket into blocking mode
293\*-------------------------------------------------------------------------*/
294void socket_setblocking(p_socket ps) {
295 u_long argp = 0;
296 ioctlsocket(*ps, FIONBIO, &argp);
297}
298
299/*-------------------------------------------------------------------------*\
300* Put socket into non-blocking mode
301\*-------------------------------------------------------------------------*/
302void socket_setnonblocking(p_socket ps) {
303 u_long argp = 1;
304 ioctlsocket(*ps, FIONBIO, &argp);
305}
306
307/*-------------------------------------------------------------------------*\
308* DNS helpers
309\*-------------------------------------------------------------------------*/
310int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
311 *hp = gethostbyaddr(addr, len, AF_INET);
312 if (*hp) return IO_DONE;
313 else return WSAGetLastError();
314}
315
316int socket_gethostbyname(const char *addr, struct hostent **hp) {
317 *hp = gethostbyname(addr);
318 if (*hp) return IO_DONE;
319 else return WSAGetLastError();
320}
321
322/*-------------------------------------------------------------------------*\
323* Error translation functions
324\*-------------------------------------------------------------------------*/
325const char *socket_hoststrerror(int err) {
326 if (err <= 0) return io_strerror(err);
327 switch (err) {
328 case WSAHOST_NOT_FOUND: return "host not found";
329 default: return wstrerror(err);
330 }
331}
332
333const char *socket_strerror(int err) {
334 if (err <= 0) return io_strerror(err);
335 switch (err) {
336 case WSAEADDRINUSE: return "address already in use";
337 case WSAECONNREFUSED: return "connection refused";
338 case WSAEISCONN: return "already connected";
339 case WSAEACCES: return "permission denied";
340 case WSAECONNABORTED: return "closed";
341 case WSAECONNRESET: return "closed";
342 case WSAETIMEDOUT: return "timeout";
343 default: return wstrerror(err);
344 }
345}
346
347const char *socket_ioerror(p_socket ps, int err) {
348 (void) ps;
349 return socket_strerror(err);
350}
351
352static const char *wstrerror(int err) {
353 switch (err) {
354 case WSAEINTR: return "Interrupted function call";
355 case WSAEACCES: return "Permission denied";
356 case WSAEFAULT: return "Bad address";
357 case WSAEINVAL: return "Invalid argument";
358 case WSAEMFILE: return "Too many open files";
359 case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
360 case WSAEINPROGRESS: return "Operation now in progress";
361 case WSAEALREADY: return "Operation already in progress";
362 case WSAENOTSOCK: return "Socket operation on nonsocket";
363 case WSAEDESTADDRREQ: return "Destination address required";
364 case WSAEMSGSIZE: return "Message too long";
365 case WSAEPROTOTYPE: return "Protocol wrong type for socket";
366 case WSAENOPROTOOPT: return "Bad protocol option";
367 case WSAEPROTONOSUPPORT: return "Protocol not supported";
368 case WSAESOCKTNOSUPPORT: return "Socket type not supported";
369 case WSAEOPNOTSUPP: return "Operation not supported";
370 case WSAEPFNOSUPPORT: return "Protocol family not supported";
371 case WSAEAFNOSUPPORT:
372 return "Address family not supported by protocol family";
373 case WSAEADDRINUSE: return "Address already in use";
374 case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
375 case WSAENETDOWN: return "Network is down";
376 case WSAENETUNREACH: return "Network is unreachable";
377 case WSAENETRESET: return "Network dropped connection on reset";
378 case WSAECONNABORTED: return "Software caused connection abort";
379 case WSAECONNRESET: return "Connection reset by peer";
380 case WSAENOBUFS: return "No buffer space available";
381 case WSAEISCONN: return "Socket is already connected";
382 case WSAENOTCONN: return "Socket is not connected";
383 case WSAESHUTDOWN: return "Cannot send after socket shutdown";
384 case WSAETIMEDOUT: return "Connection timed out";
385 case WSAECONNREFUSED: return "Connection refused";
386 case WSAEHOSTDOWN: return "Host is down";
387 case WSAEHOSTUNREACH: return "No route to host";
388 case WSAEPROCLIM: return "Too many processes";
389 case WSASYSNOTREADY: return "Network subsystem is unavailable";
390 case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range";
391 case WSANOTINITIALISED:
392 return "Successful WSAStartup not yet performed";
393 case WSAEDISCON: return "Graceful shutdown in progress";
394 case WSAHOST_NOT_FOUND: return "Host not found";
395 case WSATRY_AGAIN: return "Nonauthoritative host not found";
396 case WSANO_RECOVERY: return "Nonrecoverable name lookup error";
397 case WSANO_DATA: return "Valid name, no data record of requested type";
398 default: return "Unknown error";
399 }
400}
401
402const char *socket_gaistrerror(int err) {
403 if (err == 0) return NULL;
404 switch (err) {
405 case EAI_AGAIN: return "temporary failure in name resolution";
406 case EAI_BADFLAGS: return "invalid value for ai_flags";
407#ifdef EAI_BADHINTS
408 case EAI_BADHINTS: return "invalid value for hints";
409#endif
410 case EAI_FAIL: return "non-recoverable failure in name resolution";
411 case EAI_FAMILY: return "ai_family not supported";
412 case EAI_MEMORY: return "memory allocation failure";
413 case EAI_NONAME:
414 return "host or service not provided, or not known";
415#ifdef EAI_OVERFLOW
416 case EAI_OVERFLOW: return "argument buffer overflow";
417#endif
418#ifdef EAI_PROTOCOL
419 case EAI_PROTOCOL: return "resolved protocol is unknown";
420#endif
421 case EAI_SERVICE: return "service not supported for socket type";
422 case EAI_SOCKTYPE: return "ai_socktype not supported";
423#ifdef EAI_SYSTEM
424 case EAI_SYSTEM: return strerror(errno);
425#endif
426 default: return gai_strerror(err);
427 }
428}
429
diff --git a/vendor/luasec/src/luasocket/wsocket.h b/vendor/luasec/src/luasocket/wsocket.h
new file mode 100644
index 00000000..c5a4b1ce
--- /dev/null
+++ b/vendor/luasec/src/luasocket/wsocket.h
@@ -0,0 +1,38 @@
1#ifndef WSOCKET_H
2#define WSOCKET_H
3/*=========================================================================*\
4* Socket compatibilization module for Win32
5* LuaSocket toolkit
6\*=========================================================================*/
7
8/*=========================================================================*\
9* WinSock include files
10\*=========================================================================*/
11#include <winsock2.h>
12#include <ws2tcpip.h>
13
14typedef int socklen_t;
15typedef SOCKADDR_STORAGE t_sockaddr_storage;
16typedef SOCKET t_socket;
17typedef t_socket *p_socket;
18
19#define WAITFD_R 1
20#define WAITFD_W 2
21#define WAITFD_E 4
22#define WAITFD_C (WAITFD_E|WAITFD_W)
23
24#ifndef IPV6_V6ONLY
25#define IPV6_V6ONLY 27
26#endif
27
28#define SOCKET_INVALID (INVALID_SOCKET)
29
30#ifndef SO_REUSEPORT
31#define SO_REUSEPORT SO_REUSEADDR
32#endif
33
34#ifndef AI_NUMERICSERV
35#define AI_NUMERICSERV (0)
36#endif
37
38#endif /* WSOCKET_H */
diff --git a/vendor/luasec/src/options.c b/vendor/luasec/src/options.c
new file mode 100644
index 00000000..3d17d6d5
--- /dev/null
+++ b/vendor/luasec/src/options.c
@@ -0,0 +1,185 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2006-2023 Bruno Silvestre
5 *
6 *--------------------------------------------------------------------------*/
7
8#include <openssl/ssl.h>
9
10#include "options.h"
11
12/* If you need to generate these options again, see options.lua */
13
14
15/*
16 OpenSSL version: OpenSSL 3.0.8
17*/
18
19static lsec_ssl_option_t ssl_options[] = {
20#if defined(SSL_OP_ALL)
21 {"all", SSL_OP_ALL},
22#endif
23#if defined(SSL_OP_ALLOW_CLIENT_RENEGOTIATION)
24 {"allow_client_renegotiation", SSL_OP_ALLOW_CLIENT_RENEGOTIATION},
25#endif
26#if defined(SSL_OP_ALLOW_NO_DHE_KEX)
27 {"allow_no_dhe_kex", SSL_OP_ALLOW_NO_DHE_KEX},
28#endif
29#if defined(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)
30 {"allow_unsafe_legacy_renegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION},
31#endif
32#if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)
33 {"cipher_server_preference", SSL_OP_CIPHER_SERVER_PREFERENCE},
34#endif
35#if defined(SSL_OP_CISCO_ANYCONNECT)
36 {"cisco_anyconnect", SSL_OP_CISCO_ANYCONNECT},
37#endif
38#if defined(SSL_OP_CLEANSE_PLAINTEXT)
39 {"cleanse_plaintext", SSL_OP_CLEANSE_PLAINTEXT},
40#endif
41#if defined(SSL_OP_COOKIE_EXCHANGE)
42 {"cookie_exchange", SSL_OP_COOKIE_EXCHANGE},
43#endif
44#if defined(SSL_OP_CRYPTOPRO_TLSEXT_BUG)
45 {"cryptopro_tlsext_bug", SSL_OP_CRYPTOPRO_TLSEXT_BUG},
46#endif
47#if defined(SSL_OP_DISABLE_TLSEXT_CA_NAMES)
48 {"disable_tlsext_ca_names", SSL_OP_DISABLE_TLSEXT_CA_NAMES},
49#endif
50#if defined(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
51 {"dont_insert_empty_fragments", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS},
52#endif
53#if defined(SSL_OP_ENABLE_KTLS)
54 {"enable_ktls", SSL_OP_ENABLE_KTLS},
55#endif
56#if defined(SSL_OP_ENABLE_MIDDLEBOX_COMPAT)
57 {"enable_middlebox_compat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT},
58#endif
59#if defined(SSL_OP_EPHEMERAL_RSA)
60 {"ephemeral_rsa", SSL_OP_EPHEMERAL_RSA},
61#endif
62#if defined(SSL_OP_IGNORE_UNEXPECTED_EOF)
63 {"ignore_unexpected_eof", SSL_OP_IGNORE_UNEXPECTED_EOF},
64#endif
65#if defined(SSL_OP_LEGACY_SERVER_CONNECT)
66 {"legacy_server_connect", SSL_OP_LEGACY_SERVER_CONNECT},
67#endif
68#if defined(SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
69 {"microsoft_big_sslv3_buffer", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER},
70#endif
71#if defined(SSL_OP_MICROSOFT_SESS_ID_BUG)
72 {"microsoft_sess_id_bug", SSL_OP_MICROSOFT_SESS_ID_BUG},
73#endif
74#if defined(SSL_OP_MSIE_SSLV2_RSA_PADDING)
75 {"msie_sslv2_rsa_padding", SSL_OP_MSIE_SSLV2_RSA_PADDING},
76#endif
77#if defined(SSL_OP_NETSCAPE_CA_DN_BUG)
78 {"netscape_ca_dn_bug", SSL_OP_NETSCAPE_CA_DN_BUG},
79#endif
80#if defined(SSL_OP_NETSCAPE_CHALLENGE_BUG)
81 {"netscape_challenge_bug", SSL_OP_NETSCAPE_CHALLENGE_BUG},
82#endif
83#if defined(SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG)
84 {"netscape_demo_cipher_change_bug", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG},
85#endif
86#if defined(SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)
87 {"netscape_reuse_cipher_change_bug", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG},
88#endif
89#if defined(SSL_OP_NO_ANTI_REPLAY)
90 {"no_anti_replay", SSL_OP_NO_ANTI_REPLAY},
91#endif
92#if defined(SSL_OP_NO_COMPRESSION)
93 {"no_compression", SSL_OP_NO_COMPRESSION},
94#endif
95#if defined(SSL_OP_NO_DTLS_MASK)
96 {"no_dtls_mask", SSL_OP_NO_DTLS_MASK},
97#endif
98#if defined(SSL_OP_NO_DTLSv1)
99 {"no_dtlsv1", SSL_OP_NO_DTLSv1},
100#endif
101#if defined(SSL_OP_NO_DTLSv1_2)
102 {"no_dtlsv1_2", SSL_OP_NO_DTLSv1_2},
103#endif
104#if defined(SSL_OP_NO_ENCRYPT_THEN_MAC)
105 {"no_encrypt_then_mac", SSL_OP_NO_ENCRYPT_THEN_MAC},
106#endif
107#if defined(SSL_OP_NO_EXTENDED_MASTER_SECRET)
108 {"no_extended_master_secret", SSL_OP_NO_EXTENDED_MASTER_SECRET},
109#endif
110#if defined(SSL_OP_NO_QUERY_MTU)
111 {"no_query_mtu", SSL_OP_NO_QUERY_MTU},
112#endif
113#if defined(SSL_OP_NO_RENEGOTIATION)
114 {"no_renegotiation", SSL_OP_NO_RENEGOTIATION},
115#endif
116#if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
117 {"no_session_resumption_on_renegotiation", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION},
118#endif
119#if defined(SSL_OP_NO_SSL_MASK)
120 {"no_ssl_mask", SSL_OP_NO_SSL_MASK},
121#endif
122#if defined(SSL_OP_NO_SSLv2)
123 {"no_sslv2", SSL_OP_NO_SSLv2},
124#endif
125#if defined(SSL_OP_NO_SSLv3)
126 {"no_sslv3", SSL_OP_NO_SSLv3},
127#endif
128#if defined(SSL_OP_NO_TICKET)
129 {"no_ticket", SSL_OP_NO_TICKET},
130#endif
131#if defined(SSL_OP_NO_TLSv1)
132 {"no_tlsv1", SSL_OP_NO_TLSv1},
133#endif
134#if defined(SSL_OP_NO_TLSv1_1)
135 {"no_tlsv1_1", SSL_OP_NO_TLSv1_1},
136#endif
137#if defined(SSL_OP_NO_TLSv1_2)
138 {"no_tlsv1_2", SSL_OP_NO_TLSv1_2},
139#endif
140#if defined(SSL_OP_NO_TLSv1_3)
141 {"no_tlsv1_3", SSL_OP_NO_TLSv1_3},
142#endif
143#if defined(SSL_OP_PKCS1_CHECK_1)
144 {"pkcs1_check_1", SSL_OP_PKCS1_CHECK_1},
145#endif
146#if defined(SSL_OP_PKCS1_CHECK_2)
147 {"pkcs1_check_2", SSL_OP_PKCS1_CHECK_2},
148#endif
149#if defined(SSL_OP_PRIORITIZE_CHACHA)
150 {"prioritize_chacha", SSL_OP_PRIORITIZE_CHACHA},
151#endif
152#if defined(SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
153 {"safari_ecdhe_ecdsa_bug", SSL_OP_SAFARI_ECDHE_ECDSA_BUG},
154#endif
155#if defined(SSL_OP_SINGLE_DH_USE)
156 {"single_dh_use", SSL_OP_SINGLE_DH_USE},
157#endif
158#if defined(SSL_OP_SINGLE_ECDH_USE)
159 {"single_ecdh_use", SSL_OP_SINGLE_ECDH_USE},
160#endif
161#if defined(SSL_OP_SSLEAY_080_CLIENT_DH_BUG)
162 {"ssleay_080_client_dh_bug", SSL_OP_SSLEAY_080_CLIENT_DH_BUG},
163#endif
164#if defined(SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG)
165 {"sslref2_reuse_cert_type_bug", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG},
166#endif
167#if defined(SSL_OP_TLSEXT_PADDING)
168 {"tlsext_padding", SSL_OP_TLSEXT_PADDING},
169#endif
170#if defined(SSL_OP_TLS_BLOCK_PADDING_BUG)
171 {"tls_block_padding_bug", SSL_OP_TLS_BLOCK_PADDING_BUG},
172#endif
173#if defined(SSL_OP_TLS_D5_BUG)
174 {"tls_d5_bug", SSL_OP_TLS_D5_BUG},
175#endif
176#if defined(SSL_OP_TLS_ROLLBACK_BUG)
177 {"tls_rollback_bug", SSL_OP_TLS_ROLLBACK_BUG},
178#endif
179 {NULL, 0L}
180};
181
182LSEC_API lsec_ssl_option_t* lsec_get_ssl_options() {
183 return ssl_options;
184}
185
diff --git a/vendor/luasec/src/options.h b/vendor/luasec/src/options.h
new file mode 100644
index 00000000..c72d52d0
--- /dev/null
+++ b/vendor/luasec/src/options.h
@@ -0,0 +1,22 @@
1#ifndef LSEC_OPTIONS_H
2#define LSEC_OPTIONS_H
3
4/*--------------------------------------------------------------------------
5 * LuaSec 1.3.2
6 *
7 * Copyright (C) 2006-2023 Bruno Silvestre
8 *
9 *--------------------------------------------------------------------------*/
10
11#include "compat.h"
12
13struct lsec_ssl_option_s {
14 const char *name;
15 unsigned long code;
16};
17
18typedef struct lsec_ssl_option_s lsec_ssl_option_t;
19
20LSEC_API lsec_ssl_option_t* lsec_get_ssl_options();
21
22#endif
diff --git a/vendor/luasec/src/options.lua b/vendor/luasec/src/options.lua
new file mode 100644
index 00000000..72428c01
--- /dev/null
+++ b/vendor/luasec/src/options.lua
@@ -0,0 +1,93 @@
1local function usage()
2 print("Usage:")
3 print("* Generate options of your system:")
4 print(" lua options.lua -g /path/to/ssl.h [version] > options.c")
5 print("* Examples:")
6 print(" lua options.lua -g /usr/include/openssl/ssl.h > options.c\n")
7 print(" lua options.lua -g /usr/include/openssl/ssl.h \"OpenSSL 1.1.1f\" > options.c\n")
8
9 print("* List options of your system:")
10 print(" lua options.lua -l /path/to/ssl.h\n")
11end
12
13--
14local function printf(str, ...)
15 print(string.format(str, ...))
16end
17
18local function generate(options, version)
19 print([[
20/*--------------------------------------------------------------------------
21 * LuaSec 1.3.2
22 *
23 * Copyright (C) 2006-2023 Bruno Silvestre
24 *
25 *--------------------------------------------------------------------------*/
26
27#include <openssl/ssl.h>
28
29#include "options.h"
30
31/* If you need to generate these options again, see options.lua */
32
33]])
34
35 printf([[
36/*
37 OpenSSL version: %s
38*/
39]], version)
40
41 print([[static lsec_ssl_option_t ssl_options[] = {]])
42
43 for k, option in ipairs(options) do
44 local name = string.lower(string.sub(option, 8))
45 print(string.format([[#if defined(%s)]], option))
46 print(string.format([[ {"%s", %s},]], name, option))
47 print([[#endif]])
48 end
49 print([[ {NULL, 0L}]])
50 print([[
51};
52
53LSEC_API lsec_ssl_option_t* lsec_get_ssl_options() {
54 return ssl_options;
55}
56]])
57end
58
59local function loadoptions(file)
60 local options = {}
61 local f = assert(io.open(file, "r"))
62 for line in f:lines() do
63 local op = string.match(line, "define%s+(SSL_OP_BIT%()")
64 if not op then
65 op = string.match(line, "define%s+(SSL_OP_%S+)")
66 if op then
67 table.insert(options, op)
68 end
69 end
70 end
71 table.sort(options, function(a,b) return a<b end)
72 return options
73end
74--
75
76local options
77local flag, file, version = ...
78
79version = version or "Unknown"
80
81if not file then
82 usage()
83elseif flag == "-g" then
84 options = loadoptions(file)
85 generate(options, version)
86elseif flag == "-l" then
87 options = loadoptions(file)
88 for k, option in ipairs(options) do
89 print(option)
90 end
91else
92 usage()
93end
diff --git a/vendor/luasec/src/ssl.c b/vendor/luasec/src/ssl.c
new file mode 100644
index 00000000..934bb81b
--- /dev/null
+++ b/vendor/luasec/src/ssl.c
@@ -0,0 +1,1092 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2014-2023 Kim Alvefur, Paul Aurich, Tobias Markmann, Matthew Wild
5 * Copyright (C) 2006-2023 Bruno Silvestre
6 *
7 *--------------------------------------------------------------------------*/
8
9#include <errno.h>
10#include <string.h>
11
12#if defined(WIN32)
13#include <winsock2.h>
14#endif
15
16#include <openssl/ssl.h>
17#include <openssl/x509v3.h>
18#include <openssl/x509_vfy.h>
19#include <openssl/err.h>
20#include <openssl/dh.h>
21
22#include <lua.h>
23#include <lauxlib.h>
24
25#include <luasocket/io.h>
26#include <luasocket/buffer.h>
27#include <luasocket/timeout.h>
28#include <luasocket/socket.h>
29
30#include "x509.h"
31#include "context.h"
32#include "ssl.h"
33
34
35#ifndef LSEC_API_OPENSSL_1_1_0
36#define SSL_is_server(s) (s->server)
37#define SSL_up_ref(ssl) CRYPTO_add(&(ssl)->references, 1, CRYPTO_LOCK_SSL)
38#define X509_up_ref(c) CRYPTO_add(&c->references, 1, CRYPTO_LOCK_X509)
39#endif
40
41
42/**
43 * Underline socket error.
44 */
45static int lsec_socket_error()
46{
47#if defined(WIN32)
48 return WSAGetLastError();
49#else
50#if defined(LSEC_OPENSSL_ERRNO_BUG)
51 // Bug in OpenSSL
52 if (errno == 0)
53 return LSEC_IO_SSL;
54#endif
55 return errno;
56#endif
57}
58
59/**
60 * Map error code into string.
61 */
62static const char *ssl_ioerror(void *ctx, int err)
63{
64 if (err == LSEC_IO_SSL) {
65 p_ssl ssl = (p_ssl) ctx;
66 switch(ssl->error) {
67 case SSL_ERROR_NONE: return "No error";
68 case SSL_ERROR_ZERO_RETURN: return "closed";
69 case SSL_ERROR_WANT_READ: return "wantread";
70 case SSL_ERROR_WANT_WRITE: return "wantwrite";
71 case SSL_ERROR_WANT_CONNECT: return "'connect' not completed";
72 case SSL_ERROR_WANT_ACCEPT: return "'accept' not completed";
73 case SSL_ERROR_WANT_X509_LOOKUP: return "Waiting for callback";
74 case SSL_ERROR_SYSCALL: return "System error";
75 case SSL_ERROR_SSL: return ERR_reason_error_string(ERR_get_error());
76 default: return "Unknown SSL error";
77 }
78 }
79 return socket_strerror(err);
80}
81
82/**
83 * Close the connection before the GC collect the object.
84 */
85static int meth_destroy(lua_State *L)
86{
87 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
88 if (ssl->state == LSEC_STATE_CONNECTED) {
89 socket_setblocking(&ssl->sock);
90 SSL_shutdown(ssl->ssl);
91 }
92 if (ssl->sock != SOCKET_INVALID) {
93 socket_destroy(&ssl->sock);
94 }
95 ssl->state = LSEC_STATE_CLOSED;
96 if (ssl->ssl) {
97 /* Clear the registries */
98 luaL_getmetatable(L, "SSL:Verify:Registry");
99 lua_pushlightuserdata(L, (void*)ssl->ssl);
100 lua_pushnil(L);
101 lua_settable(L, -3);
102 luaL_getmetatable(L, "SSL:SNI:Registry");
103 lua_pushlightuserdata(L, (void*)ssl->ssl);
104 lua_pushnil(L);
105 lua_settable(L, -3);
106 /* Destroy the object */
107 SSL_free(ssl->ssl);
108 ssl->ssl = NULL;
109 }
110 return 0;
111}
112
113/**
114 * Perform the TLS/SSL handshake
115 */
116static int handshake(p_ssl ssl)
117{
118 int err;
119 p_timeout tm = timeout_markstart(&ssl->tm);
120 if (ssl->state == LSEC_STATE_CLOSED)
121 return IO_CLOSED;
122 for ( ; ; ) {
123 ERR_clear_error();
124 err = SSL_do_handshake(ssl->ssl);
125 ssl->error = SSL_get_error(ssl->ssl, err);
126 switch (ssl->error) {
127 case SSL_ERROR_NONE:
128 ssl->state = LSEC_STATE_CONNECTED;
129 return IO_DONE;
130 case SSL_ERROR_WANT_READ:
131 err = socket_waitfd(&ssl->sock, WAITFD_R, tm);
132 if (err == IO_TIMEOUT) return LSEC_IO_SSL;
133 if (err != IO_DONE) return err;
134 break;
135 case SSL_ERROR_WANT_WRITE:
136 err = socket_waitfd(&ssl->sock, WAITFD_W, tm);
137 if (err == IO_TIMEOUT) return LSEC_IO_SSL;
138 if (err != IO_DONE) return err;
139 break;
140 case SSL_ERROR_SYSCALL:
141 if (ERR_peek_error()) {
142 ssl->error = SSL_ERROR_SSL;
143 return LSEC_IO_SSL;
144 }
145 if (err == 0)
146 return IO_CLOSED;
147 return lsec_socket_error();
148 default:
149 return LSEC_IO_SSL;
150 }
151 }
152 return IO_UNKNOWN;
153}
154
155/**
156 * Send data
157 */
158static int ssl_send(void *ctx, const char *data, size_t count, size_t *sent,
159 p_timeout tm)
160{
161 int err;
162 p_ssl ssl = (p_ssl)ctx;
163 if (ssl->state != LSEC_STATE_CONNECTED)
164 return IO_CLOSED;
165 *sent = 0;
166 for ( ; ; ) {
167 ERR_clear_error();
168 err = SSL_write(ssl->ssl, data, (int)count);
169 ssl->error = SSL_get_error(ssl->ssl, err);
170 switch (ssl->error) {
171 case SSL_ERROR_NONE:
172 *sent = err;
173 return IO_DONE;
174 case SSL_ERROR_WANT_READ:
175 err = socket_waitfd(&ssl->sock, WAITFD_R, tm);
176 if (err == IO_TIMEOUT) return LSEC_IO_SSL;
177 if (err != IO_DONE) return err;
178 break;
179 case SSL_ERROR_WANT_WRITE:
180 err = socket_waitfd(&ssl->sock, WAITFD_W, tm);
181 if (err == IO_TIMEOUT) return LSEC_IO_SSL;
182 if (err != IO_DONE) return err;
183 break;
184 case SSL_ERROR_SYSCALL:
185 if (ERR_peek_error()) {
186 ssl->error = SSL_ERROR_SSL;
187 return LSEC_IO_SSL;
188 }
189 if (err == 0)
190 return IO_CLOSED;
191 return lsec_socket_error();
192 default:
193 return LSEC_IO_SSL;
194 }
195 }
196 return IO_UNKNOWN;
197}
198
199/**
200 * Receive data
201 */
202static int ssl_recv(void *ctx, char *data, size_t count, size_t *got,
203 p_timeout tm)
204{
205 int err;
206 p_ssl ssl = (p_ssl)ctx;
207 *got = 0;
208 if (ssl->state != LSEC_STATE_CONNECTED)
209 return IO_CLOSED;
210 for ( ; ; ) {
211 ERR_clear_error();
212 err = SSL_read(ssl->ssl, data, (int)count);
213 ssl->error = SSL_get_error(ssl->ssl, err);
214 switch (ssl->error) {
215 case SSL_ERROR_NONE:
216 *got = err;
217 return IO_DONE;
218 case SSL_ERROR_ZERO_RETURN:
219 return IO_CLOSED;
220 case SSL_ERROR_WANT_READ:
221 err = socket_waitfd(&ssl->sock, WAITFD_R, tm);
222 if (err == IO_TIMEOUT) return LSEC_IO_SSL;
223 if (err != IO_DONE) return err;
224 break;
225 case SSL_ERROR_WANT_WRITE:
226 err = socket_waitfd(&ssl->sock, WAITFD_W, tm);
227 if (err == IO_TIMEOUT) return LSEC_IO_SSL;
228 if (err != IO_DONE) return err;
229 break;
230 case SSL_ERROR_SYSCALL:
231 if (ERR_peek_error()) {
232 ssl->error = SSL_ERROR_SSL;
233 return LSEC_IO_SSL;
234 }
235 if (err == 0)
236 return IO_CLOSED;
237 return lsec_socket_error();
238 default:
239 return LSEC_IO_SSL;
240 }
241 }
242 return IO_UNKNOWN;
243}
244
245static SSL_CTX* luaossl_testcontext(lua_State *L, int arg) {
246 SSL_CTX **ctx = luaL_testudata(L, arg, "SSL_CTX*");
247 if (ctx)
248 return *ctx;
249 return NULL;
250}
251
252static SSL* luaossl_testssl(lua_State *L, int arg) {
253 SSL **ssl = luaL_testudata(L, arg, "SSL*");
254 if (ssl)
255 return *ssl;
256 return NULL;
257}
258
259/**
260 * Create a new TLS/SSL object and mark it as new.
261 */
262static int meth_create(lua_State *L)
263{
264 p_ssl ssl;
265 int mode;
266 SSL_CTX *ctx;
267
268 lua_settop(L, 1);
269
270 ssl = (p_ssl)lua_newuserdata(L, sizeof(t_ssl));
271 if (!ssl) {
272 lua_pushnil(L);
273 lua_pushstring(L, "error creating SSL object");
274 return 2;
275 }
276
277 if ((ctx = lsec_testcontext(L, 1))) {
278 mode = lsec_getmode(L, 1);
279 if (mode == LSEC_MODE_INVALID) {
280 lua_pushnil(L);
281 lua_pushstring(L, "invalid mode");
282 return 2;
283 }
284 ssl->ssl = SSL_new(ctx);
285 if (!ssl->ssl) {
286 lua_pushnil(L);
287 lua_pushfstring(L, "error creating SSL object (%s)",
288 ERR_reason_error_string(ERR_get_error()));
289 return 2;
290 }
291 } else if ((ctx = luaossl_testcontext(L, 1))) {
292 ssl->ssl = SSL_new(ctx);
293 if (!ssl->ssl) {
294 lua_pushnil(L);
295 lua_pushfstring(L, "error creating SSL object (%s)",
296 ERR_reason_error_string(ERR_get_error()));
297 return 2;
298 }
299 mode = SSL_is_server(ssl->ssl) ? LSEC_MODE_SERVER : LSEC_MODE_CLIENT;
300 } else if ((ssl->ssl = luaossl_testssl(L, 1))) {
301 SSL_up_ref(ssl->ssl);
302 mode = SSL_is_server(ssl->ssl) ? LSEC_MODE_SERVER : LSEC_MODE_CLIENT;
303 } else {
304 return luaL_argerror(L, 1, "invalid context");
305 }
306 ssl->state = LSEC_STATE_NEW;
307 SSL_set_fd(ssl->ssl, (int)SOCKET_INVALID);
308 SSL_set_mode(ssl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
309 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
310 SSL_set_mode(ssl->ssl, SSL_MODE_RELEASE_BUFFERS);
311 if (mode == LSEC_MODE_SERVER)
312 SSL_set_accept_state(ssl->ssl);
313 else
314 SSL_set_connect_state(ssl->ssl);
315
316 io_init(&ssl->io, (p_send)ssl_send, (p_recv)ssl_recv,
317 (p_error) ssl_ioerror, ssl);
318 timeout_init(&ssl->tm, -1, -1);
319 buffer_init(&ssl->buf, &ssl->io, &ssl->tm);
320
321 luaL_getmetatable(L, "SSL:Connection");
322 lua_setmetatable(L, -2);
323 return 1;
324}
325
326/**
327 * Buffer send function
328 */
329static int meth_send(lua_State *L) {
330 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
331 return buffer_meth_send(L, &ssl->buf);
332}
333
334/**
335 * Buffer receive function
336 */
337static int meth_receive(lua_State *L) {
338 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
339 return buffer_meth_receive(L, &ssl->buf);
340}
341
342/**
343 * Get the buffer's statistics.
344 */
345static int meth_getstats(lua_State *L) {
346 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
347 return buffer_meth_getstats(L, &ssl->buf);
348}
349
350/**
351 * Set the buffer's statistics.
352 */
353static int meth_setstats(lua_State *L) {
354 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
355 return buffer_meth_setstats(L, &ssl->buf);
356}
357
358/**
359 * Select support methods
360 */
361static int meth_getfd(lua_State *L)
362{
363 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
364 lua_pushnumber(L, ssl->sock);
365 return 1;
366}
367
368/**
369 * Set the TLS/SSL file descriptor.
370 * Call it *before* the handshake.
371 */
372static int meth_setfd(lua_State *L)
373{
374 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
375 if (ssl->state != LSEC_STATE_NEW)
376 luaL_argerror(L, 1, "invalid SSL object state");
377 ssl->sock = (t_socket)luaL_checkinteger(L, 2);
378 socket_setnonblocking(&ssl->sock);
379 SSL_set_fd(ssl->ssl, (int)ssl->sock);
380 return 0;
381}
382
383/**
384 * Lua handshake function.
385 */
386static int meth_handshake(lua_State *L)
387{
388 int err;
389 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
390 p_context ctx = (p_context)SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl->ssl));
391 ctx->L = L;
392 err = handshake(ssl);
393 if (ctx->dh_param) {
394 DH_free(ctx->dh_param);
395 ctx->dh_param = NULL;
396 }
397 if (ctx->alpn) {
398 free(ctx->alpn);
399 ctx->alpn = NULL;
400 }
401 if (err == IO_DONE) {
402 lua_pushboolean(L, 1);
403 return 1;
404 }
405 lua_pushboolean(L, 0);
406 lua_pushstring(L, ssl_ioerror((void*)ssl, err));
407 return 2;
408}
409
410/**
411 * Close the connection.
412 */
413static int meth_close(lua_State *L)
414{
415 meth_destroy(L);
416 return 0;
417}
418
419/**
420 * Set timeout.
421 */
422static int meth_settimeout(lua_State *L)
423{
424 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
425 return timeout_meth_settimeout(L, &ssl->tm);
426}
427
428/**
429 * Check if there is data in the buffer.
430 */
431static int meth_dirty(lua_State *L)
432{
433 int res = 0;
434 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
435 if (ssl->state != LSEC_STATE_CLOSED)
436 res = !buffer_isempty(&ssl->buf) || SSL_pending(ssl->ssl);
437 lua_pushboolean(L, res);
438 return 1;
439}
440
441/**
442 * Return the state information about the SSL object.
443 */
444static int meth_want(lua_State *L)
445{
446 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
447 int code = (ssl->state == LSEC_STATE_CLOSED)
448 ? SSL_NOTHING
449 : SSL_want(ssl->ssl);
450 switch(code) {
451 case SSL_NOTHING: lua_pushstring(L, "nothing"); break;
452 case SSL_READING: lua_pushstring(L, "read"); break;
453 case SSL_WRITING: lua_pushstring(L, "write"); break;
454 case SSL_X509_LOOKUP: lua_pushstring(L, "x509lookup"); break;
455 }
456 return 1;
457}
458
459/**
460 * Return the compression method used.
461 */
462static int meth_compression(lua_State *L)
463{
464#ifdef OPENSSL_NO_COMP
465 const void *comp;
466#else
467 const COMP_METHOD *comp;
468#endif
469 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
470 if (ssl->state != LSEC_STATE_CONNECTED) {
471 lua_pushnil(L);
472 lua_pushstring(L, "closed");
473 return 2;
474 }
475 comp = SSL_get_current_compression(ssl->ssl);
476 if (comp)
477 lua_pushstring(L, SSL_COMP_get_name(comp));
478 else
479 lua_pushnil(L);
480 return 1;
481}
482
483/**
484 * Return the nth certificate of the peer's chain.
485 */
486static int meth_getpeercertificate(lua_State *L)
487{
488 int n;
489 X509 *cert;
490 STACK_OF(X509) *certs;
491 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
492 if (ssl->state != LSEC_STATE_CONNECTED) {
493 lua_pushnil(L);
494 lua_pushstring(L, "closed");
495 return 2;
496 }
497 /* Default to the first cert */
498 n = (int)luaL_optinteger(L, 2, 1);
499 /* This function is 1-based, but OpenSSL is 0-based */
500 --n;
501 if (n < 0) {
502 lua_pushnil(L);
503 lua_pushliteral(L, "invalid certificate index");
504 return 2;
505 }
506 if (n == 0) {
507 cert = SSL_get_peer_certificate(ssl->ssl);
508 if (cert)
509 lsec_pushx509(L, cert);
510 else
511 lua_pushnil(L);
512 return 1;
513 }
514 /* In a server-context, the stack doesn't contain the peer cert,
515 * so adjust accordingly.
516 */
517 if (SSL_is_server(ssl->ssl))
518 --n;
519 certs = SSL_get_peer_cert_chain(ssl->ssl);
520 if (n >= sk_X509_num(certs)) {
521 lua_pushnil(L);
522 return 1;
523 }
524 cert = sk_X509_value(certs, n);
525 /* Increment the reference counting of the object. */
526 /* See SSL_get_peer_certificate() source code. */
527 X509_up_ref(cert);
528 lsec_pushx509(L, cert);
529 return 1;
530}
531
532/**
533 * Return the nth certificate of the chain sent to our peer.
534 */
535static int meth_getlocalcertificate(lua_State *L)
536{
537 int n;
538 X509 *cert;
539 STACK_OF(X509) *certs;
540 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
541 if (ssl->state != LSEC_STATE_CONNECTED) {
542 lua_pushnil(L);
543 lua_pushstring(L, "closed");
544 return 2;
545 }
546 /* Default to the first cert */
547 n = (int)luaL_optinteger(L, 2, 1);
548 /* This function is 1-based, but OpenSSL is 0-based */
549 --n;
550 if (n < 0) {
551 lua_pushnil(L);
552 lua_pushliteral(L, "invalid certificate index");
553 return 2;
554 }
555 if (n == 0) {
556 cert = SSL_get_certificate(ssl->ssl);
557 if (cert)
558 lsec_pushx509(L, cert);
559 else
560 lua_pushnil(L);
561 return 1;
562 }
563 /* In a server-context, the stack doesn't contain the peer cert,
564 * so adjust accordingly.
565 */
566 if (SSL_is_server(ssl->ssl))
567 --n;
568 if(SSL_get0_chain_certs(ssl->ssl, &certs) != 1) {
569 lua_pushnil(L);
570 } else {
571 if (n >= sk_X509_num(certs)) {
572 lua_pushnil(L);
573 return 1;
574 }
575 cert = sk_X509_value(certs, n);
576 /* Increment the reference counting of the object. */
577 /* See SSL_get_peer_certificate() source code. */
578 X509_up_ref(cert);
579 lsec_pushx509(L, cert);
580 }
581 return 1;
582}
583
584/**
585 * Return the chain of certificate of the peer.
586 */
587static int meth_getpeerchain(lua_State *L)
588{
589 int i;
590 int idx = 1;
591 int n_certs;
592 X509 *cert;
593 STACK_OF(X509) *certs;
594 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
595 if (ssl->state != LSEC_STATE_CONNECTED) {
596 lua_pushnil(L);
597 lua_pushstring(L, "closed");
598 return 2;
599 }
600 lua_newtable(L);
601 if (SSL_is_server(ssl->ssl)) {
602 lsec_pushx509(L, SSL_get_peer_certificate(ssl->ssl));
603 lua_rawseti(L, -2, idx++);
604 }
605 certs = SSL_get_peer_cert_chain(ssl->ssl);
606 n_certs = sk_X509_num(certs);
607 for (i = 0; i < n_certs; i++) {
608 cert = sk_X509_value(certs, i);
609 /* Increment the reference counting of the object. */
610 /* See SSL_get_peer_certificate() source code. */
611 X509_up_ref(cert);
612 lsec_pushx509(L, cert);
613 lua_rawseti(L, -2, idx++);
614 }
615 return 1;
616}
617
618/**
619 * Return the chain of certificates sent to the peer.
620 */
621static int meth_getlocalchain(lua_State *L)
622{
623 int i;
624 int idx = 1;
625 int n_certs;
626 X509 *cert;
627 STACK_OF(X509) *certs;
628 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
629 if (ssl->state != LSEC_STATE_CONNECTED) {
630 lua_pushnil(L);
631 lua_pushstring(L, "closed");
632 return 2;
633 }
634 lua_newtable(L);
635 if (SSL_is_server(ssl->ssl)) {
636 lsec_pushx509(L, SSL_get_certificate(ssl->ssl));
637 lua_rawseti(L, -2, idx++);
638 }
639 if(SSL_get0_chain_certs(ssl->ssl, &certs)) {
640 n_certs = sk_X509_num(certs);
641 for (i = 0; i < n_certs; i++) {
642 cert = sk_X509_value(certs, i);
643 /* Increment the reference counting of the object. */
644 /* See SSL_get_peer_certificate() source code. */
645 X509_up_ref(cert);
646 lsec_pushx509(L, cert);
647 lua_rawseti(L, -2, idx++);
648 }
649 }
650 return 1;
651}
652
653/**
654 * Copy the table src to the table dst.
655 */
656static void copy_error_table(lua_State *L, int src, int dst)
657{
658 lua_pushnil(L);
659 while (lua_next(L, src) != 0) {
660 if (lua_istable(L, -1)) {
661 /* Replace the table with its copy */
662 lua_newtable(L);
663 copy_error_table(L, dst+2, dst+3);
664 lua_remove(L, dst+2);
665 }
666 lua_pushvalue(L, -2);
667 lua_pushvalue(L, -2);
668 lua_rawset(L, dst);
669 /* Remove the value and leave the key */
670 lua_pop(L, 1);
671 }
672}
673
674/**
675 * Return the verification state of the peer chain.
676 */
677static int meth_getpeerverification(lua_State *L)
678{
679 long err;
680 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
681 if (ssl->state != LSEC_STATE_CONNECTED) {
682 lua_pushboolean(L, 0);
683 lua_pushstring(L, "closed");
684 return 2;
685 }
686 err = SSL_get_verify_result(ssl->ssl);
687 if (err == X509_V_OK) {
688 lua_pushboolean(L, 1);
689 return 1;
690 }
691 luaL_getmetatable(L, "SSL:Verify:Registry");
692 lua_pushlightuserdata(L, (void*)ssl->ssl);
693 lua_gettable(L, -2);
694 if (lua_isnil(L, -1))
695 lua_pushstring(L, X509_verify_cert_error_string(err));
696 else {
697 /* Copy the table of errors to avoid modifications */
698 lua_newtable(L);
699 copy_error_table(L, lua_gettop(L)-1, lua_gettop(L));
700 }
701 lua_pushboolean(L, 0);
702 lua_pushvalue(L, -2);
703 return 2;
704}
705
706/**
707 * Get the latest "Finished" message sent out.
708 */
709static int meth_getfinished(lua_State *L)
710{
711 size_t len = 0;
712 char *buffer = NULL;
713 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
714 if (ssl->state != LSEC_STATE_CONNECTED) {
715 lua_pushnil(L);
716 lua_pushstring(L, "closed");
717 return 2;
718 }
719 if ((len = SSL_get_finished(ssl->ssl, NULL, 0)) == 0)
720 return 0;
721 buffer = (char*)malloc(len);
722 if (!buffer) {
723 lua_pushnil(L);
724 lua_pushstring(L, "out of memory");
725 return 2;
726 }
727 SSL_get_finished(ssl->ssl, buffer, len);
728 lua_pushlstring(L, buffer, len);
729 free(buffer);
730 return 1;
731}
732
733/**
734 * Gets the latest "Finished" message received.
735 */
736static int meth_getpeerfinished(lua_State *L)
737{
738 size_t len = 0;
739 char *buffer = NULL;
740 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
741 if (ssl->state != LSEC_STATE_CONNECTED) {
742 lua_pushnil(L);
743 lua_pushstring(L, "closed");
744 return 0;
745 }
746 if ((len = SSL_get_peer_finished(ssl->ssl, NULL, 0)) == 0)
747 return 0;
748 buffer = (char*)malloc(len);
749 if (!buffer) {
750 lua_pushnil(L);
751 lua_pushstring(L, "out of memory");
752 return 2;
753 }
754 SSL_get_peer_finished(ssl->ssl, buffer, len);
755 lua_pushlstring(L, buffer, len);
756 free(buffer);
757 return 1;
758}
759
760/**
761 * Get some shared keying material
762 */
763static int meth_exportkeyingmaterial(lua_State *L)
764{
765 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
766
767 if(ssl->state != LSEC_STATE_CONNECTED) {
768 lua_pushnil(L);
769 lua_pushstring(L, "closed");
770 return 0;
771 }
772
773 size_t llen = 0;
774 size_t contextlen = 0;
775 const unsigned char *context = NULL;
776 const char *label = (const char*)luaL_checklstring(L, 2, &llen);
777 size_t olen = (size_t)luaL_checkinteger(L, 3);
778
779 if (!lua_isnoneornil(L, 4))
780 context = (const unsigned char*)luaL_checklstring(L, 4, &contextlen);
781
782 /* Temporary buffer memory-managed by Lua itself */
783 unsigned char *out = (unsigned char*)lua_newuserdata(L, olen);
784
785 if(SSL_export_keying_material(ssl->ssl, out, olen, label, llen, context, contextlen, context != NULL) != 1) {
786 lua_pushnil(L);
787 lua_pushstring(L, "error exporting keying material");
788 return 2;
789 }
790
791 lua_pushlstring(L, (char*)out, olen);
792 return 1;
793}
794
795/**
796 * Object information -- tostring metamethod
797 */
798static int meth_tostring(lua_State *L)
799{
800 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
801 lua_pushfstring(L, "SSL connection: %p%s", ssl,
802 ssl->state == LSEC_STATE_CLOSED ? " (closed)" : "");
803 return 1;
804}
805
806/**
807 * Add a method in the SSL metatable.
808 */
809static int meth_setmethod(lua_State *L)
810{
811 luaL_getmetatable(L, "SSL:Connection");
812 lua_pushstring(L, "__index");
813 lua_gettable(L, -2);
814 lua_pushvalue(L, 1);
815 lua_pushvalue(L, 2);
816 lua_settable(L, -3);
817 return 0;
818}
819
820/**
821 * Return information about the connection.
822 */
823static int meth_info(lua_State *L)
824{
825 int bits = 0;
826 int algbits = 0;
827 char buf[256] = {0};
828 const SSL_CIPHER *cipher;
829 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
830 cipher = SSL_get_current_cipher(ssl->ssl);
831 if (!cipher)
832 return 0;
833 SSL_CIPHER_description(cipher, buf, sizeof(buf));
834 bits = SSL_CIPHER_get_bits(cipher, &algbits);
835 lua_pushstring(L, buf);
836 lua_pushnumber(L, bits);
837 lua_pushnumber(L, algbits);
838 lua_pushstring(L, SSL_get_version(ssl->ssl));
839 return 4;
840}
841
842static int sni_cb(SSL *ssl, int *ad, void *arg)
843{
844 int strict;
845 SSL_CTX *newctx = NULL;
846 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
847 lua_State *L = ((p_context)SSL_CTX_get_app_data(ctx))->L;
848 const char *name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
849 /* No name, use default context */
850 if (!name)
851 return SSL_TLSEXT_ERR_NOACK;
852 /* Retrieve struct from registry */
853 luaL_getmetatable(L, "SSL:SNI:Registry");
854 lua_pushlightuserdata(L, (void*)ssl);
855 lua_gettable(L, -2);
856 /* Strict search? */
857 lua_pushstring(L, "strict");
858 lua_gettable(L, -2);
859 strict = lua_toboolean(L, -1);
860 lua_pop(L, 1);
861 /* Search for the name in the map */
862 lua_pushstring(L, "map");
863 lua_gettable(L, -2);
864 lua_pushstring(L, name);
865 lua_gettable(L, -2);
866 if (lua_isuserdata(L, -1))
867 newctx = lsec_checkcontext(L, -1);
868 lua_pop(L, 4);
869 /* Found, use this context */
870 if (newctx) {
871 p_context pctx = (p_context)SSL_CTX_get_app_data(newctx);
872 pctx->L = L;
873 SSL_set_SSL_CTX(ssl, newctx);
874 return SSL_TLSEXT_ERR_OK;
875 }
876 /* Not found, but use initial context */
877 if (!strict)
878 return SSL_TLSEXT_ERR_OK;
879 return SSL_TLSEXT_ERR_ALERT_FATAL;
880}
881
882static int meth_sni(lua_State *L)
883{
884 int strict;
885 SSL_CTX *aux;
886 const char *name;
887 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
888 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl->ssl);
889 p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
890 if (pctx->mode == LSEC_MODE_CLIENT) {
891 name = luaL_checkstring(L, 2);
892 SSL_set_tlsext_host_name(ssl->ssl, name);
893 return 0;
894 } else if (pctx->mode == LSEC_MODE_SERVER) {
895 luaL_checktype(L, 2, LUA_TTABLE);
896 strict = lua_toboolean(L, 3);
897 /* Check if the table contains only (string -> context) */
898 lua_pushnil(L);
899 while (lua_next(L, 2)) {
900 luaL_checkstring(L, -2);
901 aux = lsec_checkcontext(L, -1);
902 /* Set callback in every context */
903 SSL_CTX_set_tlsext_servername_callback(aux, sni_cb);
904 /* leave the next key on the stack */
905 lua_pop(L, 1);
906 }
907 /* Save table in the register */
908 luaL_getmetatable(L, "SSL:SNI:Registry");
909 lua_pushlightuserdata(L, (void*)ssl->ssl);
910 lua_newtable(L);
911 lua_pushstring(L, "map");
912 lua_pushvalue(L, 2);
913 lua_settable(L, -3);
914 lua_pushstring(L, "strict");
915 lua_pushboolean(L, strict);
916 lua_settable(L, -3);
917 lua_settable(L, -3);
918 /* Set callback in the default context */
919 SSL_CTX_set_tlsext_servername_callback(ctx, sni_cb);
920 }
921 return 0;
922}
923
924static int meth_getsniname(lua_State *L)
925{
926 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
927 const char *name = SSL_get_servername(ssl->ssl, TLSEXT_NAMETYPE_host_name);
928 if (name)
929 lua_pushstring(L, name);
930 else
931 lua_pushnil(L);
932 return 1;
933}
934
935static int meth_getalpn(lua_State *L)
936{
937 unsigned len;
938 const unsigned char *data;
939 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
940 SSL_get0_alpn_selected(ssl->ssl, &data, &len);
941 if (data == NULL && len == 0)
942 lua_pushnil(L);
943 else
944 lua_pushlstring(L, (const char*)data, len);
945 return 1;
946}
947
948static int meth_copyright(lua_State *L)
949{
950 lua_pushstring(L, "LuaSec 1.3.2 - Copyright (C) 2006-2023 Bruno Silvestre, UFG"
951#if defined(WITH_LUASOCKET)
952 "\nLuaSocket 3.0-RC1 - Copyright (C) 2004-2013 Diego Nehab"
953#endif
954 );
955 return 1;
956}
957
958#if defined(LSEC_ENABLE_DANE)
959static int meth_dane(lua_State *L)
960{
961 int ret;
962 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
963 ret = SSL_dane_enable(ssl->ssl, luaL_checkstring(L, 2));
964 lua_pushboolean(L, (ret > 0));
965 return 1;
966}
967
968static int meth_tlsa(lua_State *L)
969{
970 int ret;
971 size_t len;
972 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
973 uint8_t usage = (uint8_t)luaL_checkinteger(L, 2);
974 uint8_t selector = (uint8_t)luaL_checkinteger(L, 3);
975 uint8_t mtype = (uint8_t)luaL_checkinteger(L, 4);
976 unsigned char *data = (unsigned char*)luaL_checklstring(L, 5, &len);
977
978 ERR_clear_error();
979 ret = SSL_dane_tlsa_add(ssl->ssl, usage, selector, mtype, data, len);
980 lua_pushboolean(L, (ret > 0));
981
982 return 1;
983}
984#endif
985
986/*---------------------------------------------------------------------------*/
987
988/**
989 * SSL methods
990 */
991static luaL_Reg methods[] = {
992 {"close", meth_close},
993 {"getalpn", meth_getalpn},
994 {"getfd", meth_getfd},
995 {"getfinished", meth_getfinished},
996 {"getpeercertificate", meth_getpeercertificate},
997 {"getlocalcertificate", meth_getlocalcertificate},
998 {"getpeerchain", meth_getpeerchain},
999 {"getlocalchain", meth_getlocalchain},
1000 {"getpeerverification", meth_getpeerverification},
1001 {"getpeerfinished", meth_getpeerfinished},
1002 {"exportkeyingmaterial",meth_exportkeyingmaterial},
1003 {"getsniname", meth_getsniname},
1004 {"getstats", meth_getstats},
1005 {"setstats", meth_setstats},
1006 {"dirty", meth_dirty},
1007 {"dohandshake", meth_handshake},
1008 {"receive", meth_receive},
1009 {"send", meth_send},
1010 {"settimeout", meth_settimeout},
1011 {"sni", meth_sni},
1012 {"want", meth_want},
1013#if defined(LSEC_ENABLE_DANE)
1014 {"setdane", meth_dane},
1015 {"settlsa", meth_tlsa},
1016#endif
1017 {NULL, NULL}
1018};
1019
1020/**
1021 * SSL metamethods.
1022 */
1023static luaL_Reg meta[] = {
1024 {"__close", meth_destroy},
1025 {"__gc", meth_destroy},
1026 {"__tostring", meth_tostring},
1027 {NULL, NULL}
1028};
1029
1030/**
1031 * SSL functions.
1032 */
1033static luaL_Reg funcs[] = {
1034 {"compression", meth_compression},
1035 {"create", meth_create},
1036 {"info", meth_info},
1037 {"setfd", meth_setfd},
1038 {"setmethod", meth_setmethod},
1039 {"copyright", meth_copyright},
1040 {NULL, NULL}
1041};
1042
1043/**
1044 * Initialize modules.
1045 */
1046LSEC_API int luaopen_ssl_core(lua_State *L)
1047{
1048#ifndef LSEC_API_OPENSSL_1_1_0
1049 /* Initialize SSL */
1050 if (!SSL_library_init()) {
1051 lua_pushstring(L, "unable to initialize SSL library");
1052 lua_error(L);
1053 }
1054 OpenSSL_add_all_algorithms();
1055 SSL_load_error_strings();
1056#endif
1057
1058#if defined(WITH_LUASOCKET)
1059 /* Initialize internal library */
1060 socket_open();
1061#endif
1062
1063 luaL_newmetatable(L, "SSL:SNI:Registry");
1064
1065 /* Register the functions and tables */
1066 luaL_newmetatable(L, "SSL:Connection");
1067 setfuncs(L, meta);
1068
1069 luaL_newlib(L, methods);
1070 lua_setfield(L, -2, "__index");
1071
1072 luaL_newlib(L, funcs);
1073
1074 lua_pushstring(L, "SOCKET_INVALID");
1075 lua_pushinteger(L, SOCKET_INVALID);
1076 lua_rawset(L, -3);
1077
1078 return 1;
1079}
1080
1081//------------------------------------------------------------------------------
1082
1083#if defined(_MSC_VER)
1084
1085/* Empty implementation to allow building with LuaRocks and MS compilers */
1086LSEC_API int luaopen_ssl(lua_State *L) {
1087 lua_pushstring(L, "you should not call this function");
1088 lua_error(L);
1089 return 0;
1090}
1091
1092#endif
diff --git a/vendor/luasec/src/ssl.h b/vendor/luasec/src/ssl.h
new file mode 100644
index 00000000..2362ffe5
--- /dev/null
+++ b/vendor/luasec/src/ssl.h
@@ -0,0 +1,41 @@
1#ifndef LSEC_SSL_H
2#define LSEC_SSL_H
3
4/*--------------------------------------------------------------------------
5 * LuaSec 1.3.2
6 *
7 * Copyright (C) 2006-2023 Bruno Silvestre
8 *
9 *--------------------------------------------------------------------------*/
10
11#include <openssl/ssl.h>
12#include <lua.h>
13
14#include <luasocket/io.h>
15#include <luasocket/buffer.h>
16#include <luasocket/timeout.h>
17#include <luasocket/socket.h>
18
19#include "compat.h"
20#include "context.h"
21
22#define LSEC_STATE_NEW 1
23#define LSEC_STATE_CONNECTED 2
24#define LSEC_STATE_CLOSED 3
25
26#define LSEC_IO_SSL -100
27
28typedef struct t_ssl_ {
29 t_socket sock;
30 t_io io;
31 t_buffer buf;
32 t_timeout tm;
33 SSL *ssl;
34 int state;
35 int error;
36} t_ssl;
37typedef t_ssl* p_ssl;
38
39LSEC_API int luaopen_ssl_core(lua_State *L);
40
41#endif
diff --git a/vendor/luasec/src/ssl.lua b/vendor/luasec/src/ssl.lua
new file mode 100644
index 00000000..e22c047e
--- /dev/null
+++ b/vendor/luasec/src/ssl.lua
@@ -0,0 +1,313 @@
1------------------------------------------------------------------------------
2-- LuaSec 1.3.2
3--
4-- Copyright (C) 2006-2023 Bruno Silvestre
5--
6------------------------------------------------------------------------------
7
8local core = require("ssl.core")
9local context = require("ssl.context")
10local x509 = require("ssl.x509")
11local config = require("ssl.config")
12
13local unpack = table.unpack or unpack
14
15-- We must prevent the contexts to be collected before the connections,
16-- otherwise the C registry will be cleared.
17local registry = setmetatable({}, {__mode="k"})
18
19--
20--
21--
22local function optexec(func, param, ctx)
23 if param then
24 if type(param) == "table" then
25 return func(ctx, unpack(param))
26 else
27 return func(ctx, param)
28 end
29 end
30 return true
31end
32
33--
34-- Convert an array of strings to wire-format
35--
36local function array2wireformat(array)
37 local str = ""
38 for k, v in ipairs(array) do
39 if type(v) ~= "string" then return nil end
40 local len = #v
41 if len == 0 then
42 return nil, "invalid ALPN name (empty string)"
43 elseif len > 255 then
44 return nil, "invalid ALPN name (length > 255)"
45 end
46 str = str .. string.char(len) .. v
47 end
48 if str == "" then return nil, "invalid ALPN list (empty)" end
49 return str
50end
51
52--
53-- Convert wire-string format to array
54--
55local function wireformat2array(str)
56 local i = 1
57 local array = {}
58 while i < #str do
59 local len = str:byte(i)
60 array[#array + 1] = str:sub(i + 1, i + len)
61 i = i + len + 1
62 end
63 return array
64end
65
66--
67--
68--
69local function newcontext(cfg)
70 local succ, msg, ctx
71 -- Create the context
72 ctx, msg = context.create(cfg.protocol)
73 if not ctx then return nil, msg end
74 -- Mode
75 succ, msg = context.setmode(ctx, cfg.mode)
76 if not succ then return nil, msg end
77 local certificates = cfg.certificates
78 if not certificates then
79 certificates = {
80 { certificate = cfg.certificate, key = cfg.key, password = cfg.password }
81 }
82 end
83 for _, certificate in ipairs(certificates) do
84 -- Load the key
85 if certificate.key then
86 if certificate.password and
87 type(certificate.password) ~= "function" and
88 type(certificate.password) ~= "string"
89 then
90 return nil, "invalid password type"
91 end
92 succ, msg = context.loadkey(ctx, certificate.key, certificate.password)
93 if not succ then return nil, msg end
94 end
95 -- Load the certificate(s)
96 if certificate.certificate then
97 succ, msg = context.loadcert(ctx, certificate.certificate)
98 if not succ then return nil, msg end
99 if certificate.key and context.checkkey then
100 succ = context.checkkey(ctx)
101 if not succ then return nil, "private key does not match public key" end
102 end
103 end
104 end
105 -- Load the CA certificates
106 if cfg.cafile or cfg.capath then
107 succ, msg = context.locations(ctx, cfg.cafile, cfg.capath)
108 if not succ then return nil, msg end
109 end
110 -- Set SSL ciphers
111 if cfg.ciphers then
112 succ, msg = context.setcipher(ctx, cfg.ciphers)
113 if not succ then return nil, msg end
114 end
115 -- Set SSL cipher suites
116 if cfg.ciphersuites then
117 succ, msg = context.setciphersuites(ctx, cfg.ciphersuites)
118 if not succ then return nil, msg end
119 end
120 -- Set the verification options
121 succ, msg = optexec(context.setverify, cfg.verify, ctx)
122 if not succ then return nil, msg end
123 -- Set SSL options
124 succ, msg = optexec(context.setoptions, cfg.options, ctx)
125 if not succ then return nil, msg end
126 -- Set the depth for certificate verification
127 if cfg.depth then
128 succ, msg = context.setdepth(ctx, cfg.depth)
129 if not succ then return nil, msg end
130 end
131
132 -- NOTE: Setting DH parameters and elliptic curves needs to come after
133 -- setoptions(), in case the user has specified the single_{dh,ecdh}_use
134 -- options.
135
136 -- Set DH parameters
137 if cfg.dhparam then
138 if type(cfg.dhparam) ~= "function" then
139 return nil, "invalid DH parameter type"
140 end
141 context.setdhparam(ctx, cfg.dhparam)
142 end
143
144 -- Set elliptic curves
145 if (not config.algorithms.ec) and (cfg.curve or cfg.curveslist) then
146 return false, "elliptic curves not supported"
147 end
148 if config.capabilities.curves_list and cfg.curveslist then
149 succ, msg = context.setcurveslist(ctx, cfg.curveslist)
150 if not succ then return nil, msg end
151 elseif cfg.curve then
152 succ, msg = context.setcurve(ctx, cfg.curve)
153 if not succ then return nil, msg end
154 end
155
156 -- Set extra verification options
157 if cfg.verifyext and ctx.setverifyext then
158 succ, msg = optexec(ctx.setverifyext, cfg.verifyext, ctx)
159 if not succ then return nil, msg end
160 end
161
162 -- ALPN
163 if cfg.mode == "server" and cfg.alpn then
164 if type(cfg.alpn) == "function" then
165 local alpncb = cfg.alpn
166 -- This callback function has to return one value only
167 succ, msg = context.setalpncb(ctx, function(str)
168 local protocols = alpncb(wireformat2array(str))
169 if type(protocols) == "string" then
170 protocols = { protocols }
171 elseif type(protocols) ~= "table" then
172 return nil
173 end
174 return (array2wireformat(protocols)) -- use "()" to drop error message
175 end)
176 if not succ then return nil, msg end
177 elseif type(cfg.alpn) == "table" then
178 local protocols = cfg.alpn
179 -- check if array is valid before use it
180 succ, msg = array2wireformat(protocols)
181 if not succ then return nil, msg end
182 -- This callback function has to return one value only
183 succ, msg = context.setalpncb(ctx, function()
184 return (array2wireformat(protocols)) -- use "()" to drop error message
185 end)
186 if not succ then return nil, msg end
187 else
188 return nil, "invalid ALPN parameter"
189 end
190 elseif cfg.mode == "client" and cfg.alpn then
191 local alpn
192 if type(cfg.alpn) == "string" then
193 alpn, msg = array2wireformat({ cfg.alpn })
194 elseif type(cfg.alpn) == "table" then
195 alpn, msg = array2wireformat(cfg.alpn)
196 else
197 return nil, "invalid ALPN parameter"
198 end
199 if not alpn then return nil, msg end
200 succ, msg = context.setalpn(ctx, alpn)
201 if not succ then return nil, msg end
202 end
203
204 -- PSK
205 if config.capabilities.psk and cfg.psk then
206 if cfg.mode == "client" then
207 if type(cfg.psk) ~= "function" then
208 return nil, "invalid PSK configuration"
209 end
210 succ = context.setclientpskcb(ctx, cfg.psk)
211 if not succ then return nil, msg end
212 elseif cfg.mode == "server" then
213 if type(cfg.psk) == "function" then
214 succ, msg = context.setserverpskcb(ctx, cfg.psk)
215 if not succ then return nil, msg end
216 elseif type(cfg.psk) == "table" then
217 if type(cfg.psk.hint) == "string" and type(cfg.psk.callback) == "function" then
218 succ, msg = context.setpskhint(ctx, cfg.psk.hint)
219 if not succ then return succ, msg end
220 succ = context.setserverpskcb(ctx, cfg.psk.callback)
221 if not succ then return succ, msg end
222 else
223 return nil, "invalid PSK configuration"
224 end
225 else
226 return nil, "invalid PSK configuration"
227 end
228 end
229 end
230
231 if config.capabilities.dane and cfg.dane then
232 if type(cfg.dane) == "table" then
233 context.setdane(ctx, unpack(cfg.dane))
234 else
235 context.setdane(ctx)
236 end
237 end
238
239 return ctx
240end
241
242--
243--
244--
245local function wrap(sock, cfg)
246 local ctx, msg
247 if type(cfg) == "table" then
248 ctx, msg = newcontext(cfg)
249 if not ctx then return nil, msg end
250 else
251 ctx = cfg
252 end
253 local s, msg = core.create(ctx)
254 if s then
255 core.setfd(s, sock:getfd())
256 sock:setfd(core.SOCKET_INVALID)
257 registry[s] = ctx
258 return s
259 end
260 return nil, msg
261end
262
263--
264-- Extract connection information.
265--
266local function info(ssl, field)
267 local str, comp, err, protocol
268 comp, err = core.compression(ssl)
269 if err then
270 return comp, err
271 end
272 -- Avoid parser
273 if field == "compression" then
274 return comp
275 end
276 local info = {compression = comp}
277 str, info.bits, info.algbits, protocol = core.info(ssl)
278 if str then
279 info.cipher, info.protocol, info.key,
280 info.authentication, info.encryption, info.mac =
281 string.match(str,
282 "^(%S+)%s+(%S+)%s+Kx=(%S+)%s+Au=(%S+)%s+Enc=(%S+)%s+Mac=(%S+)")
283 info.export = (string.match(str, "%sexport%s*$") ~= nil)
284 end
285 if protocol then
286 info.protocol = protocol
287 end
288 if field then
289 return info[field]
290 end
291 -- Empty?
292 return ( (next(info)) and info )
293end
294
295--
296-- Set method for SSL connections.
297--
298core.setmethod("info", info)
299
300--------------------------------------------------------------------------------
301-- Export module
302--
303
304local _M = {
305 _VERSION = "1.3.2",
306 _COPYRIGHT = core.copyright(),
307 config = config,
308 loadcertificate = x509.load,
309 newcontext = newcontext,
310 wrap = wrap,
311}
312
313return _M
diff --git a/vendor/luasec/src/x509.c b/vendor/luasec/src/x509.c
new file mode 100644
index 00000000..6833d46f
--- /dev/null
+++ b/vendor/luasec/src/x509.c
@@ -0,0 +1,750 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2014-2023 Kim Alvefur, Paul Aurich, Tobias Markmann, Matthew Wild
5 * Copyright (C) 2014-2023 Bruno Silvestre
6 *
7 *--------------------------------------------------------------------------*/
8
9#include <stdio.h>
10#include <string.h>
11
12#if defined(WIN32)
13#include <ws2tcpip.h>
14#include <windows.h>
15#else
16#include <sys/types.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <arpa/inet.h>
20#endif
21
22#include <openssl/ssl.h>
23#include <openssl/x509v3.h>
24#include <openssl/evp.h>
25#include <openssl/err.h>
26#include <openssl/asn1.h>
27#include <openssl/bio.h>
28#include <openssl/bn.h>
29
30#include <lua.h>
31#include <lauxlib.h>
32
33#include "x509.h"
34
35
36#ifndef LSEC_API_OPENSSL_1_1_0
37#define X509_get0_notBefore X509_get_notBefore
38#define X509_get0_notAfter X509_get_notAfter
39#define ASN1_STRING_get0_data ASN1_STRING_data
40#endif
41
42static const char* hex_tab = "0123456789abcdef";
43
44/**
45 * Push the certificate on the stack.
46 */
47void lsec_pushx509(lua_State* L, X509 *cert)
48{
49 p_x509 cert_obj = (p_x509)lua_newuserdata(L, sizeof(t_x509));
50 cert_obj->cert = cert;
51 cert_obj->encode = LSEC_AI5_STRING;
52 luaL_getmetatable(L, "SSL:Certificate");
53 lua_setmetatable(L, -2);
54}
55
56/**
57 * Return the OpenSSL certificate X509.
58 */
59X509* lsec_checkx509(lua_State* L, int idx)
60{
61 return ((p_x509)luaL_checkudata(L, idx, "SSL:Certificate"))->cert;
62}
63
64/**
65 * Return LuaSec certificate X509 representation.
66 */
67p_x509 lsec_checkp_x509(lua_State* L, int idx)
68{
69 return (p_x509)luaL_checkudata(L, idx, "SSL:Certificate");
70}
71
72/*---------------------------------------------------------------------------*/
73
74#if defined(LUASEC_INET_NTOP)
75/*
76 * For WinXP (SP3), set the following preprocessor macros:
77 * LUASEC_INET_NTOP
78 * WINVER=0x0501
79 * _WIN32_WINNT=0x0501
80 * NTDDI_VERSION=0x05010300
81 *
82 * For IPv6 addresses, you need to add IPv6 Protocol to your interface.
83 *
84 */
85static const char *inet_ntop(int af, const char *src, char *dst, socklen_t size)
86{
87 int addrsize;
88 struct sockaddr *addr;
89 struct sockaddr_in addr4;
90 struct sockaddr_in6 addr6;
91
92 switch (af) {
93 case AF_INET:
94 memset((void*)&addr4, 0, sizeof(addr4));
95 addr4.sin_family = AF_INET;
96 memcpy((void*)&addr4.sin_addr, src, sizeof(struct in_addr));
97 addr = (struct sockaddr*)&addr4;
98 addrsize = sizeof(struct sockaddr_in);
99 break;
100 case AF_INET6:
101 memset((void*)&addr6, 0, sizeof(addr6));
102 addr6.sin6_family = AF_INET6;
103 memcpy((void*)&addr6.sin6_addr, src, sizeof(struct in6_addr));
104 addr = (struct sockaddr*)&addr6;
105 addrsize = sizeof(struct sockaddr_in6);
106 break;
107 default:
108 return NULL;
109 }
110
111 if(getnameinfo(addr, addrsize, dst, size, NULL, 0, NI_NUMERICHOST) != 0)
112 return NULL;
113 return dst;
114}
115#endif
116
117/*---------------------------------------------------------------------------*/
118
119/**
120 * Convert the buffer 'in' to hexadecimal.
121 */
122static void to_hex(const char* in, int length, char* out)
123{
124 int i;
125 for (i = 0; i < length; i++) {
126 out[i*2] = hex_tab[(in[i] >> 4) & 0xF];
127 out[i*2+1] = hex_tab[(in[i]) & 0xF];
128 }
129}
130
131/**
132 * Converts the ASN1_OBJECT into a textual representation and put it
133 * on the Lua stack.
134 */
135static void push_asn1_objname(lua_State* L, ASN1_OBJECT *object, int no_name)
136{
137 char buffer[256];
138 int len = OBJ_obj2txt(buffer, sizeof(buffer), object, no_name);
139 len = (len < sizeof(buffer)) ? len : sizeof(buffer);
140 lua_pushlstring(L, buffer, len);
141}
142
143/**
144 * Push the ASN1 string on the stack.
145 */
146static void push_asn1_string(lua_State* L, ASN1_STRING *string, int encode)
147{
148 int len;
149 unsigned char *data;
150 if (!string) {
151 lua_pushnil(L);
152 return;
153 }
154 switch (encode) {
155 case LSEC_AI5_STRING:
156 lua_pushlstring(L, (char*)ASN1_STRING_get0_data(string), ASN1_STRING_length(string));
157 break;
158 case LSEC_UTF8_STRING:
159 len = ASN1_STRING_to_UTF8(&data, string);
160 if (len >= 0) {
161 lua_pushlstring(L, (char*)data, len);
162 OPENSSL_free(data);
163 }
164 else
165 lua_pushnil(L);
166 }
167}
168
169/**
170 * Return a human readable time.
171 */
172static int push_asn1_time(lua_State *L, const ASN1_UTCTIME *tm)
173{
174 char *tmp;
175 long size;
176 BIO *out = BIO_new(BIO_s_mem());
177 ASN1_TIME_print(out, tm);
178 size = BIO_get_mem_data(out, &tmp);
179 lua_pushlstring(L, tmp, size);
180 BIO_free(out);
181 return 1;
182}
183
184/**
185 * Return a human readable IP address.
186 */
187static void push_asn1_ip(lua_State *L, ASN1_STRING *string)
188{
189 int af;
190 char dst[INET6_ADDRSTRLEN];
191 unsigned char *ip = (unsigned char*)ASN1_STRING_get0_data(string);
192 switch(ASN1_STRING_length(string)) {
193 case 4:
194 af = AF_INET;
195 break;
196 case 16:
197 af = AF_INET6;
198 break;
199 default:
200 lua_pushnil(L);
201 return;
202 }
203 if(inet_ntop(af, ip, dst, INET6_ADDRSTRLEN))
204 lua_pushstring(L, dst);
205 else
206 lua_pushnil(L);
207}
208
209/**
210 *
211 */
212static int push_subtable(lua_State* L, int idx)
213{
214 lua_pushvalue(L, -1);
215 lua_gettable(L, idx-1);
216 if (lua_isnil(L, -1)) {
217 lua_pop(L, 1);
218 lua_newtable(L);
219 lua_pushvalue(L, -2);
220 lua_pushvalue(L, -2);
221 lua_settable(L, idx-3);
222 lua_replace(L, -2); /* Replace key with table */
223 return 1;
224 }
225 lua_replace(L, -2); /* Replace key with table */
226 return 0;
227}
228
229/**
230 * Retrieve the general names from the object.
231 */
232static int push_x509_name(lua_State* L, X509_NAME *name, int encode)
233{
234 int i;
235 int n_entries;
236 ASN1_OBJECT *object;
237 X509_NAME_ENTRY *entry;
238 lua_newtable(L);
239 n_entries = X509_NAME_entry_count(name);
240 for (i = 0; i < n_entries; i++) {
241 entry = X509_NAME_get_entry(name, i);
242 object = X509_NAME_ENTRY_get_object(entry);
243 lua_newtable(L);
244 push_asn1_objname(L, object, 1);
245 lua_setfield(L, -2, "oid");
246 push_asn1_objname(L, object, 0);
247 lua_setfield(L, -2, "name");
248 push_asn1_string(L, X509_NAME_ENTRY_get_data(entry), encode);
249 lua_setfield(L, -2, "value");
250 lua_rawseti(L, -2, i+1);
251 }
252 return 1;
253}
254
255/*---------------------------------------------------------------------------*/
256
257/**
258 * Retrieve the Subject from the certificate.
259 */
260static int meth_subject(lua_State* L)
261{
262 p_x509 px = lsec_checkp_x509(L, 1);
263 return push_x509_name(L, X509_get_subject_name(px->cert), px->encode);
264}
265
266/**
267 * Retrieve the Issuer from the certificate.
268 */
269static int meth_issuer(lua_State* L)
270{
271 p_x509 px = lsec_checkp_x509(L, 1);
272 return push_x509_name(L, X509_get_issuer_name(px->cert), px->encode);
273}
274
275/**
276 * Retrieve the extensions from the certificate.
277 */
278int meth_extensions(lua_State* L)
279{
280 int j;
281 int i = -1;
282 int n_general_names;
283 OTHERNAME *otherName;
284 X509_EXTENSION *extension;
285 GENERAL_NAME *general_name;
286 STACK_OF(GENERAL_NAME) *values;
287 p_x509 px = lsec_checkp_x509(L, 1);
288 X509 *peer = px->cert;
289
290 /* Return (ret) */
291 lua_newtable(L);
292
293 while ((i = X509_get_ext_by_NID(peer, NID_subject_alt_name, i)) != -1) {
294 extension = X509_get_ext(peer, i);
295 if (extension == NULL)
296 break;
297 values = X509V3_EXT_d2i(extension);
298 if (values == NULL)
299 break;
300
301 /* Push ret[oid] */
302 push_asn1_objname(L, X509_EXTENSION_get_object(extension), 1);
303 push_subtable(L, -2);
304
305 /* Set ret[oid].name = name */
306 push_asn1_objname(L, X509_EXTENSION_get_object(extension), 0);
307 lua_setfield(L, -2, "name");
308
309 n_general_names = sk_GENERAL_NAME_num(values);
310 for (j = 0; j < n_general_names; j++) {
311 general_name = sk_GENERAL_NAME_value(values, j);
312 switch (general_name->type) {
313 case GEN_OTHERNAME:
314 otherName = general_name->d.otherName;
315 push_asn1_objname(L, otherName->type_id, 1);
316 if (push_subtable(L, -2)) {
317 push_asn1_objname(L, otherName->type_id, 0);
318 lua_setfield(L, -2, "name");
319 }
320 push_asn1_string(L, otherName->value->value.asn1_string, px->encode);
321 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
322 lua_pop(L, 1);
323 break;
324 case GEN_DNS:
325 lua_pushstring(L, "dNSName");
326 push_subtable(L, -2);
327 push_asn1_string(L, general_name->d.dNSName, px->encode);
328 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
329 lua_pop(L, 1);
330 break;
331 case GEN_EMAIL:
332 lua_pushstring(L, "rfc822Name");
333 push_subtable(L, -2);
334 push_asn1_string(L, general_name->d.rfc822Name, px->encode);
335 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
336 lua_pop(L, 1);
337 break;
338 case GEN_URI:
339 lua_pushstring(L, "uniformResourceIdentifier");
340 push_subtable(L, -2);
341 push_asn1_string(L, general_name->d.uniformResourceIdentifier, px->encode);
342 lua_rawseti(L, -2, lua_rawlen(L, -2)+1);
343 lua_pop(L, 1);
344 break;
345 case GEN_IPADD:
346 lua_pushstring(L, "iPAddress");
347 push_subtable(L, -2);
348 push_asn1_ip(L, general_name->d.iPAddress);
349 lua_rawseti(L, -2, lua_rawlen(L, -2)+1);
350 lua_pop(L, 1);
351 break;
352 case GEN_X400:
353 /* x400Address */
354 /* not supported */
355 break;
356 case GEN_DIRNAME:
357 /* directoryName */
358 /* not supported */
359 break;
360 case GEN_EDIPARTY:
361 /* ediPartyName */
362 /* not supported */
363 break;
364 case GEN_RID:
365 /* registeredID */
366 /* not supported */
367 break;
368 }
369 GENERAL_NAME_free(general_name);
370 }
371 sk_GENERAL_NAME_free(values);
372 lua_pop(L, 1); /* ret[oid] */
373 i++; /* Next extension */
374 }
375 return 1;
376}
377
378/**
379 * Convert the certificate to PEM format.
380 */
381static int meth_pem(lua_State* L)
382{
383 char* data;
384 long bytes;
385 X509* cert = lsec_checkx509(L, 1);
386 BIO *bio = BIO_new(BIO_s_mem());
387 if (!PEM_write_bio_X509(bio, cert)) {
388 lua_pushnil(L);
389 return 1;
390 }
391 bytes = BIO_get_mem_data(bio, &data);
392 if (bytes > 0)
393 lua_pushlstring(L, data, bytes);
394 else
395 lua_pushnil(L);
396 BIO_free(bio);
397 return 1;
398}
399
400/**
401 * Extract public key in PEM format.
402 */
403static int meth_pubkey(lua_State* L)
404{
405 char* data;
406 long bytes;
407 int ret = 1;
408 X509* cert = lsec_checkx509(L, 1);
409 BIO *bio = BIO_new(BIO_s_mem());
410 EVP_PKEY *pkey = X509_get_pubkey(cert);
411 if(PEM_write_bio_PUBKEY(bio, pkey)) {
412 bytes = BIO_get_mem_data(bio, &data);
413 if (bytes > 0) {
414 lua_pushlstring(L, data, bytes);
415 switch(EVP_PKEY_base_id(pkey)) {
416 case EVP_PKEY_RSA:
417 lua_pushstring(L, "RSA");
418 break;
419 case EVP_PKEY_DSA:
420 lua_pushstring(L, "DSA");
421 break;
422 case EVP_PKEY_DH:
423 lua_pushstring(L, "DH");
424 break;
425 case EVP_PKEY_EC:
426 lua_pushstring(L, "EC");
427 break;
428 default:
429 lua_pushstring(L, "Unknown");
430 break;
431 }
432 lua_pushinteger(L, EVP_PKEY_bits(pkey));
433 ret = 3;
434 }
435 else
436 lua_pushnil(L);
437 }
438 else
439 lua_pushnil(L);
440 /* Cleanup */
441 BIO_free(bio);
442 EVP_PKEY_free(pkey);
443 return ret;
444}
445
446/**
447 * Compute the fingerprint.
448 */
449static int meth_digest(lua_State* L)
450{
451 unsigned int bytes;
452 const EVP_MD *digest = NULL;
453 unsigned char buffer[EVP_MAX_MD_SIZE];
454 char hex_buffer[EVP_MAX_MD_SIZE*2];
455 X509 *cert = lsec_checkx509(L, 1);
456 const char *str = luaL_optstring(L, 2, NULL);
457 if (!str)
458 digest = EVP_sha1();
459 else {
460 if (!strcmp(str, "sha1"))
461 digest = EVP_sha1();
462 else if (!strcmp(str, "sha256"))
463 digest = EVP_sha256();
464 else if (!strcmp(str, "sha512"))
465 digest = EVP_sha512();
466 }
467 if (!digest) {
468 lua_pushnil(L);
469 lua_pushfstring(L, "digest algorithm not supported (%s)", str);
470 return 2;
471 }
472 if (!X509_digest(cert, digest, buffer, &bytes)) {
473 lua_pushnil(L);
474 lua_pushfstring(L, "error processing the certificate (%s)",
475 ERR_reason_error_string(ERR_get_error()));
476 return 2;
477 }
478 to_hex((char*)buffer, bytes, hex_buffer);
479 lua_pushlstring(L, hex_buffer, bytes*2);
480 return 1;
481}
482
483/**
484 * Check if the certificate is valid in a given time.
485 */
486static int meth_valid_at(lua_State* L)
487{
488 int nb, na;
489 X509* cert = lsec_checkx509(L, 1);
490 time_t time = luaL_checkinteger(L, 2);
491 nb = X509_cmp_time(X509_get0_notBefore(cert), &time);
492 time -= 1;
493 na = X509_cmp_time(X509_get0_notAfter(cert), &time);
494 lua_pushboolean(L, nb == -1 && na == 1);
495 return 1;
496}
497
498/**
499 * Return the serial number.
500 */
501static int meth_serial(lua_State *L)
502{
503 char *tmp;
504 BIGNUM *bn;
505 ASN1_INTEGER *serial;
506 X509* cert = lsec_checkx509(L, 1);
507 serial = X509_get_serialNumber(cert);
508 bn = ASN1_INTEGER_to_BN(serial, NULL);
509 tmp = BN_bn2hex(bn);
510 lua_pushstring(L, tmp);
511 BN_free(bn);
512 OPENSSL_free(tmp);
513 return 1;
514}
515
516/**
517 * Return not before date.
518 */
519static int meth_notbefore(lua_State *L)
520{
521 X509* cert = lsec_checkx509(L, 1);
522 return push_asn1_time(L, X509_get0_notBefore(cert));
523}
524
525/**
526 * Return not after date.
527 */
528static int meth_notafter(lua_State *L)
529{
530 X509* cert = lsec_checkx509(L, 1);
531 return push_asn1_time(L, X509_get0_notAfter(cert));
532}
533
534/**
535 * Check if this certificate issued some other certificate
536 */
537static int meth_issued(lua_State* L)
538{
539 int ret, i, len;
540
541 X509_STORE_CTX* ctx = NULL;
542 X509_STORE* root = NULL;
543 STACK_OF(X509)* chain = NULL;
544
545 X509* issuer = lsec_checkx509(L, 1);
546 X509* subject = lsec_checkx509(L, 2);
547 X509* cert = NULL;
548
549 len = lua_gettop(L);
550
551 /* Check that all arguments are certificates */
552
553 for (i = 3; i <= len; i++) {
554 lsec_checkx509(L, i);
555 }
556
557 /* Before allocating things that require freeing afterwards */
558
559 chain = sk_X509_new_null();
560 ctx = X509_STORE_CTX_new();
561 root = X509_STORE_new();
562
563 if (ctx == NULL || root == NULL) {
564 lua_pushnil(L);
565 lua_pushstring(L, "X509_STORE_new() or X509_STORE_CTX_new() error");
566 ret = 2;
567 goto cleanup;
568 }
569
570 ret = X509_STORE_add_cert(root, issuer);
571
572 if(!ret) {
573 lua_pushnil(L);
574 lua_pushstring(L, "X509_STORE_add_cert() error");
575 ret = 2;
576 goto cleanup;
577 }
578
579 for (i = 3; i <= len && lua_isuserdata(L, i); i++) {
580 cert = lsec_checkx509(L, i);
581 sk_X509_push(chain, cert);
582 }
583
584 ret = X509_STORE_CTX_init(ctx, root, subject, chain);
585
586 if(!ret) {
587 lua_pushnil(L);
588 lua_pushstring(L, "X509_STORE_CTX_init() error");
589 ret = 2;
590 goto cleanup;
591 }
592
593 /* Actual verification */
594 if (X509_verify_cert(ctx) <= 0) {
595 ret = X509_STORE_CTX_get_error(ctx);
596 lua_pushnil(L);
597 lua_pushstring(L, X509_verify_cert_error_string(ret));
598 ret = 2;
599 } else {
600 lua_pushboolean(L, 1);
601 ret = 1;
602 }
603
604cleanup:
605
606 if (ctx != NULL) {
607 X509_STORE_CTX_free(ctx);
608 }
609
610 if (chain != NULL) {
611 X509_STORE_free(root);
612 }
613
614 sk_X509_free(chain);
615
616 return ret;
617}
618
619/**
620 * Collect X509 objects.
621 */
622static int meth_destroy(lua_State* L)
623{
624 p_x509 px = lsec_checkp_x509(L, 1);
625 if (px->cert) {
626 X509_free(px->cert);
627 px->cert = NULL;
628 }
629 return 0;
630}
631
632static int meth_tostring(lua_State *L)
633{
634 X509* cert = lsec_checkx509(L, 1);
635 lua_pushfstring(L, "X509 certificate: %p", cert);
636 return 1;
637}
638
639/**
640 * Set the encode for ASN.1 string.
641 */
642static int meth_set_encode(lua_State* L)
643{
644 int succ = 0;
645 p_x509 px = lsec_checkp_x509(L, 1);
646 const char *enc = luaL_checkstring(L, 2);
647 if (strncmp(enc, "ai5", 3) == 0) {
648 succ = 1;
649 px->encode = LSEC_AI5_STRING;
650 } else if (strncmp(enc, "utf8", 4) == 0) {
651 succ = 1;
652 px->encode = LSEC_UTF8_STRING;
653 }
654 lua_pushboolean(L, succ);
655 return 1;
656}
657
658#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
659/**
660 * Get signature name.
661 */
662static int meth_get_signature_name(lua_State* L)
663{
664 p_x509 px = lsec_checkp_x509(L, 1);
665 int nid = X509_get_signature_nid(px->cert);
666 const char *name = OBJ_nid2sn(nid);
667 if (!name)
668 lua_pushnil(L);
669 else
670 lua_pushstring(L, name);
671 return 1;
672}
673#endif
674
675/*---------------------------------------------------------------------------*/
676
677static int load_cert(lua_State* L)
678{
679 X509 *cert;
680 size_t bytes;
681 const char* data;
682 BIO *bio = BIO_new(BIO_s_mem());
683 data = luaL_checklstring(L, 1, &bytes);
684 BIO_write(bio, data, bytes);
685 cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
686 if (cert)
687 lsec_pushx509(L, cert);
688 else
689 lua_pushnil(L);
690 BIO_free(bio);
691 return 1;
692}
693
694/*---------------------------------------------------------------------------*/
695
696/**
697 * Certificate methods.
698 */
699static luaL_Reg methods[] = {
700 {"digest", meth_digest},
701 {"setencode", meth_set_encode},
702 {"extensions", meth_extensions},
703#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
704 {"getsignaturename", meth_get_signature_name},
705#endif
706 {"issuer", meth_issuer},
707 {"notbefore", meth_notbefore},
708 {"notafter", meth_notafter},
709 {"issued", meth_issued},
710 {"pem", meth_pem},
711 {"pubkey", meth_pubkey},
712 {"serial", meth_serial},
713 {"subject", meth_subject},
714 {"validat", meth_valid_at},
715 {NULL, NULL}
716};
717
718/**
719 * X509 metamethods.
720 */
721static luaL_Reg meta[] = {
722 {"__close", meth_destroy},
723 {"__gc", meth_destroy},
724 {"__tostring", meth_tostring},
725 {NULL, NULL}
726};
727
728/**
729 * X509 functions.
730 */
731static luaL_Reg funcs[] = {
732 {"load", load_cert},
733 {NULL, NULL}
734};
735
736/*--------------------------------------------------------------------------*/
737
738LSEC_API int luaopen_ssl_x509(lua_State *L)
739{
740 /* Register the functions and tables */
741 luaL_newmetatable(L, "SSL:Certificate");
742 setfuncs(L, meta);
743
744 luaL_newlib(L, methods);
745 lua_setfield(L, -2, "__index");
746
747 luaL_newlib(L, funcs);
748
749 return 1;
750}
diff --git a/vendor/luasec/src/x509.h b/vendor/luasec/src/x509.h
new file mode 100644
index 00000000..acdbe6c0
--- /dev/null
+++ b/vendor/luasec/src/x509.h
@@ -0,0 +1,31 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2014-2023 Kim Alvefur, Paul Aurich, Tobias Markmann, Matthew Wild
5 * Copyright (C) 2013-2023 Bruno Silvestre
6 *
7 *--------------------------------------------------------------------------*/
8
9#ifndef LSEC_X509_H
10#define LSEC_X509_H
11
12#include <openssl/x509v3.h>
13#include <lua.h>
14
15#include "compat.h"
16
17/* We do not support UniversalString nor BMPString as ASN.1 String types */
18enum { LSEC_AI5_STRING, LSEC_UTF8_STRING };
19
20typedef struct t_x509_ {
21 X509 *cert;
22 int encode;
23} t_x509;
24typedef t_x509* p_x509;
25
26void lsec_pushx509(lua_State* L, X509* cert);
27X509* lsec_checkx509(lua_State* L, int idx);
28
29LSEC_API int luaopen_ssl_x509(lua_State *L);
30
31#endif