From patchwork Wed Feb 13 22:08:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?J=C3=B6rg_Krause?= X-Patchwork-Id: 1041648 Return-Path: X-Original-To: incoming-buildroot@patchwork.ozlabs.org Delivered-To: patchwork-incoming-buildroot@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=busybox.net (client-ip=140.211.166.138; helo=whitealder.osuosl.org; envelope-from=buildroot-bounces@busybox.net; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=embedded.rocks Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 440DfD3nkKz9s7T for ; Thu, 14 Feb 2019 09:27:00 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id CFF5B85C98; Wed, 13 Feb 2019 22:26:55 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PyqayOT3FZIh; Wed, 13 Feb 2019 22:26:15 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by whitealder.osuosl.org (Postfix) with ESMTP id 1866084AFB; Wed, 13 Feb 2019 22:26:15 +0000 (UTC) X-Original-To: buildroot@lists.busybox.net Delivered-To: buildroot@osuosl.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by ash.osuosl.org (Postfix) with ESMTP id C5B331BF343 for ; Wed, 13 Feb 2019 22:09:15 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id AFC61811F4 for ; Wed, 13 Feb 2019 22:09:15 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NhOT-JlxHTce for ; Wed, 13 Feb 2019 22:08:44 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.142]) by whitealder.osuosl.org (Postfix) with ESMTPS id E042785AD6 for ; Wed, 13 Feb 2019 22:08:43 +0000 (UTC) Received: from submission (posteo.de [89.146.220.130]) by mout02.posteo.de (Postfix) with ESMTPS id D7AC52400E5 for ; Wed, 13 Feb 2019 23:08:40 +0100 (CET) Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 440DDq2McKz9rxP for ; Wed, 13 Feb 2019 23:08:26 +0100 (CET) Received: from mail.embedded.rocks ([127.0.0.1]) by localhost (mail.embedded.rocks [127.0.0.1]) (amavisd-new, port 10025) with ESMTP id nNA-U21U0Ixw; Wed, 13 Feb 2019 23:08:23 +0100 (CET) Received: from nzxt.fritz.box (port-92-193-214-47.dynamic.qsc.de [92.193.214.47]) (Authenticated sender: joerg.krause@embedded.rocks) by mail.embedded.rocks (Postfix) with ESMTPSA; Wed, 13 Feb 2019 23:08:22 +0100 (CET) From: =?utf-8?q?J=C3=B6rg_Krause?= To: buildroot@buildroot.org Date: Wed, 13 Feb 2019 23:08:11 +0100 Message-Id: <20190213220812.29978-1-joerg.krause@embedded.rocks> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-Mailman-Approved-At: Wed, 13 Feb 2019 22:26:14 +0000 Subject: [Buildroot] [PATCH] package/luvi: add patch to fix build issue with OpenSSL 1.1.1a X-BeenThere: buildroot@busybox.net X-Mailman-Version: 2.1.29 Precedence: list List-Id: Discussion and development of buildroot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: buildroot-bounces@busybox.net Sender: "buildroot" Bump the bundled lua-openssl version to 0.7.4 for compatibility with OpenSSL 1.1.1a. Note, that luvi 2.7.6 is the latest version providing a release tarball. Runtime tested on Banana Pro, note that version string for lua-openssl does not match the tag name (0.7.4): ``` luvi v2.7.6 zlib: 1.2.11 libuv: 1.25.0 ssl: OpenSSL 1.1.1a 20 Nov 2018, lua-openssl 0.7.3 ``` Fixes: http://autobuild.buildroot.net/results/e87994a3dc987f5aa101a5e721ac927e21453373 http://autobuild.buildroot.net/results/ea725ad90cfcd3c5e242268a593dcabd7297fe70 http://autobuild.buildroot.net/results/f2fb9eea0044e4a5f674742d29ea95af49cf5a45 http://autobuild.buildroot.net/results/de4daa1b930f907f06640dc98a708016217ddea5 .. and many more. Signed-off-by: Jörg Krause --- ...bundled-lua-openssl-to-version-0.7.4.patch | 31718 ++++++++++++++++ 1 file changed, 31718 insertions(+) create mode 100644 package/luvi/0003-Bump-bundled-lua-openssl-to-version-0.7.4.patch diff --git a/package/luvi/0003-Bump-bundled-lua-openssl-to-version-0.7.4.patch b/package/luvi/0003-Bump-bundled-lua-openssl-to-version-0.7.4.patch new file mode 100644 index 0000000000..339b3f759a --- /dev/null +++ b/package/luvi/0003-Bump-bundled-lua-openssl-to-version-0.7.4.patch @@ -0,0 +1,31718 @@ +Bump bundled lua-openssl to version 0.7.4 for compatibility with OpenSSL 1.1.x. + +Signed-off-by: Jörg Krause + +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/appveyor.yml luvi-src-v2.7.6/deps/lua-openssl/appveyor.yml +--- luvi-src-v2.7.6.orig/deps/lua-openssl/appveyor.yml 2019-02-13 11:31:40.277302045 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/appveyor.yml 2019-02-13 11:53:24.105128513 +0100 +@@ -9,7 +9,7 @@ install: + - git submodule update --recursive + - '"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86' + - cd C:\ +-- ps: Start-FileDownload 'https://github.com/zhaozg/openssl-win32/blob/1.0.2/misc/luv.dll?raw=true' 'C:\luv.dll' ++#- ps: Start-FileDownload 'https://github.com/zhaozg/openssl-win32/blob/1.0.2/misc/luv.dll?raw=true' -FileName 'C:\luv.dll' + #- git clone https://github.com/zhaozg/openssl-win32.git C:\openssl-win32 + - git clone http://luajit.org/git/luajit-2.0.git C:\luajit-2.0 + build_script: +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/auxiliar/auxiliar.c luvi-src-v2.7.6/deps/lua-openssl/deps/auxiliar/auxiliar.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/auxiliar/auxiliar.c 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/auxiliar/auxiliar.c 2019-02-13 11:53:29.051738872 +0100 +@@ -7,6 +7,10 @@ + + #include "auxiliar.h" + ++#if LUA_VERSION_NUM<503 ++#include "c-api/compat-5.3.h" ++#endif ++ + /*=========================================================================*\ + * Exported functions + \*=========================================================================*/ +@@ -143,7 +147,7 @@ void *auxiliar_getgroupudata(lua_State * + * otherwise + \*-------------------------------------------------------------------------*/ + void *auxiliar_getclassudata(lua_State *L, const char *classname, int objidx) { +- return luaL_checkudata(L, objidx, classname); ++ return luaL_testudata(L, objidx, classname); + } + + /*-------------------------------------------------------------------------*\ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/auxiliar/readme.md luvi-src-v2.7.6/deps/lua-openssl/deps/auxiliar/readme.md +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/auxiliar/readme.md 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/auxiliar/readme.md 2019-02-13 11:53:29.051738872 +0100 +@@ -0,0 +1,65 @@ ++# lua-auxiliar ++ ++## Introduce ++ ++The origin auxiliar is part of [luasocket](https://github.com/diegonehab/luasocket), it's a general purpose class implemention lib for userdata with metatable. ++ ++``` ++/*=========================================================================*\ ++* Auxiliar routines for class hierarchy manipulation ++* LuaSocket toolkit (but completely independent of other LuaSocket modules) ++* ++* A LuaSocket class is a name associated with Lua metatables. A LuaSocket ++* group is a name associated with a class. A class can belong to any number ++* of groups. This module provides the functionality to: ++* ++* - create new classes ++* - add classes to groups ++* - set the class of objects ++* - check if an object belongs to a given class or group ++* - get the userdata associated to objects ++* - print objects in a pretty way ++* ++* LuaSocket class names follow the convention {}. Modules ++* can define any number of classes and groups. The module tcp.c, for ++* example, defines the classes tcp{master}, tcp{client} and tcp{server} and ++* the groups tcp{client,server} and tcp{any}. Module functions can then ++* perform type-checking on their arguments by either class or group. ++* ++* LuaSocket metatables define the __index metamethod as being a table. This ++* table has one field for each method supported by the class, and a field ++* "class" with the class name. ++* ++* The mapping from class name to the corresponding metatable and the ++* reverse mapping are done using lauxlib. ++\*=========================================================================*/ ++``` ++ ++## Update ++ ++I do minimual change, and add a few APIs for [lui](https://github.com/zhaozg/lui) and [lua-openssl](https://github.com/zhaozg/lua-openssl). ++TODO more ++ ++## License ++```text ++LuaSocket 3.0 license ++Copyright © 2004-2018 Diego Nehab ++ ++Permission is hereby granted, free of charge, to any person obtaining a ++copy of this software and associated documentation files (the "Software"), ++to deal in the Software without restriction, including without limitation ++the rights to use, copy, modify, merge, publish, distribute, sublicense, ++and/or sell copies of the Software, and to permit persons to whom the ++Software is furnished to do so, subject to the following conditions: ++ ++The above copyright notice and this permission notice shall be included in ++all copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++DEALINGS IN THE SOFTWARE. ++``` +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/auxiliar/subsidiar.c luvi-src-v2.7.6/deps/lua-openssl/deps/auxiliar/subsidiar.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/auxiliar/subsidiar.c 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/auxiliar/subsidiar.c 2019-02-13 11:53:29.051738872 +0100 +@@ -0,0 +1,22 @@ ++#include "auxiliar.h" ++#include "subsidiar.h" ++ ++int auxiliar_enumerate(lua_State *L, int tidx, const LuaL_Enumeration *lenums) ++{ ++ int n = tidx < 0 ? tidx-2 : tidx; ++ const LuaL_Enumeration *e = lenums; ++ while( e->name!=NULL ) ++ { ++ lua_pushstring(L, e->name); ++ lua_pushinteger(L, e->val); ++ lua_rawset(L, n); ++ e++; ++ } ++ return 1; ++} ++ ++int auxiliar_checkoption(lua_State*L, int objidx, const char* def, const char* const slist[], const int ival[]) ++{ ++ int at = luaL_checkoption(L, objidx, def, slist); ++ return ival[at]; ++} +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/auxiliar/subsidiar.h luvi-src-v2.7.6/deps/lua-openssl/deps/auxiliar/subsidiar.h +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/auxiliar/subsidiar.h 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/auxiliar/subsidiar.h 2019-02-13 11:53:29.051738872 +0100 +@@ -0,0 +1,51 @@ ++#ifndef SUBSIDIAR_H ++#define SUBSIDIAR_H ++ ++#include "lua.h" ++#include "lauxlib.h" ++ ++/* subsidiary part for auxiliar libirary */ ++ ++#define AUXILIAR_SET(L, tidx, lvar, cval, ltype) \ ++ do { \ ++ int n = tidx < 0 ? tidx-1 : tidx; \ ++ lua_push##ltype(L, (cval)); \ ++ lua_setfield(L, n, lvar); \ ++ } while(0) ++ ++#define AUXLIAR_GET(L, tidx, lvar, cvar, ltype) \ ++ do { \ ++ lua_getfield(L, tidx, lvar); \ ++ cvar = lua_to##ltype(L, -1); \ ++ lua_pop(L, 1); \ ++ } while(0) ++ ++#define AUXILIAR_SETLSTR(L, tidx, lvar, cval, len) \ ++ do { \ ++ int n = tidx < 0 ? tidx-1 : tidx; \ ++ lua_pushlstring(L, (const char*)(cval),len); \ ++ lua_setfield(L, n, lvar); \ ++ } while(0) ++ ++#define AUXILIAR_GETLSTR(L, tidx, lvar, cvar, len) \ ++ do { \ ++ lua_getfield(L, tidx, lvar); \ ++ cvar = lua_tolstring(L, -1, &len); \ ++ lua_setfield(L, n, lvar); \ ++ } while(0) ++ ++typedef struct ++{ ++ const char* name; ++ int val; ++} LuaL_Enumeration; ++ ++int auxiliar_enumerate(lua_State *L, int tidx, const LuaL_Enumeration *lenum); ++int auxiliar_checkoption(lua_State*L, ++ int objidx, ++ const char *def, ++ const char *const slist[], ++ const int ival[]); ++ ++#endif ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/c-api/compat-5.3.c luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/c-api/compat-5.3.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/c-api/compat-5.3.c 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/c-api/compat-5.3.c 2019-02-13 11:53:29.078405237 +0100 +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + #include "compat-5.3.h" + + /* don't compile it again if it already is included via compat53.h */ +@@ -14,6 +15,75 @@ + /* definitions for Lua 5.1 only */ + #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 + ++#ifndef COMPAT53_FOPEN_NO_LOCK ++# if defined(_MSC_VER) ++# define COMPAT53_FOPEN_NO_LOCK 1 ++# else /* otherwise */ ++# define COMPAT53_FOPEN_NO_LOCK 0 ++# endif /* VC++ only so far */ ++#endif /* No-lock fopen_s usage if possible */ ++ ++#if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK ++# include ++#endif /* VC++ _fsopen for share-allowed file read */ ++ ++#ifndef COMPAT53_HAVE_STRERROR_R ++# if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || \ ++ (!defined (__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6)) ++# define COMPAT53_HAVE_STRERROR_R 1 ++# else /* none of the defines matched: define to 0 */ ++# define COMPAT53_HAVE_STRERROR_R 0 ++# endif /* have strerror_r of some form */ ++#endif /* strerror_r */ ++ ++#ifndef COMPAT53_HAVE_STRERROR_S ++# if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \ ++ defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__) ++# define COMPAT53_HAVE_STRERROR_S 1 ++# else /* not VC++ or C11 */ ++# define COMPAT53_HAVE_STRERROR_S 0 ++# endif /* strerror_s from VC++ or C11 */ ++#endif /* strerror_s */ ++ ++#ifndef COMPAT53_LUA_FILE_BUFFER_SIZE ++# define COMPAT53_LUA_FILE_BUFFER_SIZE 4096 ++#endif /* Lua File Buffer Size */ ++ ++ ++static char* compat53_strerror (int en, char* buff, size_t sz) { ++#if COMPAT53_HAVE_STRERROR_R ++ /* use strerror_r here, because it's available on these specific platforms */ ++ if (sz > 0) { ++ buff[0] = '\0'; ++ /* we don't care whether the GNU version or the XSI version is used: */ ++ if (strerror_r(en, buff, sz)) { ++ /* Yes, we really DO want to ignore the return value! ++ * GCC makes that extra hard, not even a (void) cast will do. */ ++ } ++ if (buff[0] == '\0') { ++ /* Buffer is unchanged, so we probably have called GNU strerror_r which ++ * returned a static constant string. Chances are that strerror will ++ * return the same static constant string and therefore be thread-safe. */ ++ return strerror(en); ++ } ++ } ++ return buff; /* sz is 0 *or* strerror_r wrote into the buffer */ ++#elif COMPAT53_HAVE_STRERROR_S ++ /* for MSVC and other C11 implementations, use strerror_s since it's ++ * provided by default by the libraries */ ++ strerror_s(buff, sz, en); ++ return buff; ++#else ++ /* fallback, but strerror is not guaranteed to be threadsafe due to modifying ++ * errno itself and some impls not locking a static buffer for it ... but most ++ * known systems have threadsafe errno: this might only change if the locale ++ * is changed out from under someone while this function is being called */ ++ (void)buff; ++ (void)sz; ++ return strerror(en); ++#endif ++} ++ + + COMPAT53_API int lua_absindex (lua_State *L, int i) { + if (i < 0 && i > LUA_REGISTRYINDEX) +@@ -100,15 +170,17 @@ COMPAT53_API void lua_copy (lua_State *L + + COMPAT53_API void lua_len (lua_State *L, int i) { + switch (lua_type(L, i)) { +- case LUA_TSTRING: /* fall through */ ++ case LUA_TSTRING: ++ lua_pushnumber(L, (lua_Number)lua_objlen(L, i)); ++ break; + case LUA_TTABLE: + if (!luaL_callmeta(L, i, "__len")) +- lua_pushnumber(L, (int)lua_objlen(L, i)); ++ lua_pushnumber(L, (lua_Number)lua_objlen(L, i)); + break; + case LUA_TUSERDATA: + if (luaL_callmeta(L, i, "__len")) + break; +- /* maybe fall through */ ++ /* FALLTHROUGH */ + default: + luaL_error(L, "attempt to get length of a %s value", + lua_typename(L, lua_type(L, i))); +@@ -132,15 +204,6 @@ COMPAT53_API void lua_rawsetp (lua_State + } + + +-COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum) { +- lua_Integer n = lua_tointeger(L, i); +- if (isnum != NULL) { +- *isnum = (n != 0 || lua_isnumber(L, i)); +-} +- return n; +-} +- +- + COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum) { + lua_Number n = lua_tonumber(L, i); + if (isnum != NULL) { +@@ -183,14 +246,15 @@ COMPAT53_API int luaL_getsubtable (lua_S + } + + +-COMPAT53_API int luaL_len (lua_State *L, int i) { +- int res = 0, isnum = 0; ++COMPAT53_API lua_Integer luaL_len (lua_State *L, int i) { ++ lua_Integer res = 0; ++ int isnum = 0; + luaL_checkstack(L, 1, "not enough stack slots"); + lua_len(L, i); +- res = (int)lua_tointegerx(L, -1, &isnum); ++ res = lua_tointegerx(L, -1, &isnum); + lua_pop(L, 1); + if (!isnum) +- luaL_error(L, "object length is not a number"); ++ luaL_error(L, "object length is not an integer"); + return res; + } + +@@ -233,34 +297,6 @@ COMPAT53_API void *luaL_testudata (lua_S + } + + +-COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { +- if (!luaL_callmeta(L, idx, "__tostring")) { +- int t = lua_type(L, idx); +- switch (t) { +- case LUA_TNIL: +- lua_pushliteral(L, "nil"); +- break; +- case LUA_TSTRING: +- case LUA_TNUMBER: +- lua_pushvalue(L, idx); +- break; +- case LUA_TBOOLEAN: +- if (lua_toboolean(L, idx)) +- lua_pushliteral(L, "true"); +- else +- lua_pushliteral(L, "false"); +- break; +- default: +- lua_pushfstring(L, "%s: %p", lua_typename(L, t), +- lua_topointer(L, idx)); +- break; +- } +- } +- return lua_tolstring(L, -1, len); +-} +- +- +-#if !defined(COMPAT53_IS_LUAJIT) + static int compat53_countlevels (lua_State *L) { + lua_Debug ar; + int li = 1, le = 1; +@@ -361,26 +397,221 @@ COMPAT53_API void luaL_traceback (lua_St + + + COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { ++ const char *serr = NULL; + int en = errno; /* calls to Lua API may change this value */ ++ char buf[512] = { 0 }; + if (stat) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); ++ serr = compat53_strerror(en, buf, sizeof(buf)); + if (fname) +- lua_pushfstring(L, "%s: %s", fname, strerror(en)); ++ lua_pushfstring(L, "%s: %s", fname, serr); + else +- lua_pushstring(L, strerror(en)); ++ lua_pushstring(L, serr); + lua_pushnumber(L, (lua_Number)en); + return 3; + } + } + + ++static int compat53_checkmode (lua_State *L, const char *mode, const char *modename, int err) { ++ if (mode && strchr(mode, modename[0]) == NULL) { ++ lua_pushfstring(L, "attempt to load a %s chunk (mode is '%s')", modename, mode); ++ return err; ++ } ++ return LUA_OK; ++} ++ ++ ++typedef struct { ++ lua_Reader reader; ++ void *ud; ++ int has_peeked_data; ++ const char *peeked_data; ++ size_t peeked_data_size; ++} compat53_reader_data; ++ ++ ++static const char *compat53_reader (lua_State *L, void *ud, size_t *size) { ++ compat53_reader_data *data = (compat53_reader_data *)ud; ++ if (data->has_peeked_data) { ++ data->has_peeked_data = 0; ++ *size = data->peeked_data_size; ++ return data->peeked_data; ++ } else ++ return data->reader(L, data->ud, size); ++} ++ ++ ++COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char *source, const char *mode) { ++ int status = LUA_OK; ++ compat53_reader_data compat53_data = { reader, data, 1, 0, 0 }; ++ compat53_data.peeked_data = reader(L, data, &(compat53_data.peeked_data_size)); ++ if (compat53_data.peeked_data && compat53_data.peeked_data_size && ++ compat53_data.peeked_data[0] == LUA_SIGNATURE[0]) /* binary file? */ ++ status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX); ++ else ++ status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX); ++ if (status != LUA_OK) ++ return status; ++ /* we need to call the original 5.1 version of lua_load! */ ++#undef lua_load ++ return lua_load(L, compat53_reader, &compat53_data, source); ++#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53) ++} ++ ++ ++typedef struct { ++ int n; /* number of pre-read characters */ ++ FILE *f; /* file being read */ ++ char buff[COMPAT53_LUA_FILE_BUFFER_SIZE]; /* area for reading file */ ++} compat53_LoadF; ++ ++ ++static const char *compat53_getF (lua_State *L, void *ud, size_t *size) { ++ compat53_LoadF *lf = (compat53_LoadF *)ud; ++ (void)L; /* not used */ ++ if (lf->n > 0) { /* are there pre-read characters to be read? */ ++ *size = lf->n; /* return them (chars already in buffer) */ ++ lf->n = 0; /* no more pre-read characters */ ++ } ++ else { /* read a block from file */ ++ /* 'fread' can return > 0 *and* set the EOF flag. If next call to ++ 'compat53_getF' called 'fread', it might still wait for user input. ++ The next check avoids this problem. */ ++ if (feof(lf->f)) return NULL; ++ *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ ++ } ++ return lf->buff; ++} ++ ++ ++static int compat53_errfile (lua_State *L, const char *what, int fnameindex) { ++ char buf[512] = {0}; ++ const char *serr = compat53_strerror(errno, buf, sizeof(buf)); ++ const char *filename = lua_tostring(L, fnameindex) + 1; ++ lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); ++ lua_remove(L, fnameindex); ++ return LUA_ERRFILE; ++} ++ ++ ++static int compat53_skipBOM (compat53_LoadF *lf) { ++ const char *p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */ ++ int c; ++ lf->n = 0; ++ do { ++ c = getc(lf->f); ++ if (c == EOF || c != *(const unsigned char *)p++) return c; ++ lf->buff[lf->n++] = (char)c; /* to be read by the parser */ ++ } while (*p != '\0'); ++ lf->n = 0; /* prefix matched; discard it */ ++ return getc(lf->f); /* return next character */ ++} ++ ++ ++/* ++** reads the first character of file 'f' and skips an optional BOM mark ++** in its beginning plus its first line if it starts with '#'. Returns ++** true if it skipped the first line. In any case, '*cp' has the ++** first "valid" character of the file (after the optional BOM and ++** a first-line comment). ++*/ ++static int compat53_skipcomment (compat53_LoadF *lf, int *cp) { ++ int c = *cp = compat53_skipBOM(lf); ++ if (c == '#') { /* first line is a comment (Unix exec. file)? */ ++ do { /* skip first line */ ++ c = getc(lf->f); ++ } while (c != EOF && c != '\n'); ++ *cp = getc(lf->f); /* skip end-of-line, if present */ ++ return 1; /* there was a comment */ ++ } ++ else return 0; /* no comment */ ++} ++ ++ ++COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode) { ++ compat53_LoadF lf; ++ int status, readstatus; ++ int c; ++ int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ ++ if (filename == NULL) { ++ lua_pushliteral(L, "=stdin"); ++ lf.f = stdin; ++ } ++ else { ++ lua_pushfstring(L, "@%s", filename); ++#if defined(_MSC_VER) ++ /* This code is here to stop a deprecation error that stops builds ++ * if a certain macro is defined. While normally not caring would ++ * be best, some header-only libraries and builds can't afford to ++ * dictate this to the user. A quick check shows that fopen_s this ++ * goes back to VS 2005, and _fsopen goes back to VS 2003 .NET, ++ * possibly even before that so we don't need to do any version ++ * number checks, since this has been there since forever. */ ++ ++ /* TO USER: if you want the behavior of typical fopen_s/fopen, ++ * which does lock the file on VC++, define the macro used below to 0 */ ++#if COMPAT53_FOPEN_NO_LOCK ++ lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */ ++ if (lf.f == NULL) ++ return compat53_errfile(L, "open", fnameindex); ++#else /* use default locking version */ ++ if (fopen_s(&lf.f, filename, "r") != 0) ++ return compat53_errfile(L, "open", fnameindex); ++#endif /* Locking vs. No-locking fopen variants */ ++#else ++ lf.f = fopen(filename, "r"); /* default stdlib doesn't forcefully lock files here */ ++ if (lf.f == NULL) return compat53_errfile(L, "open", fnameindex); ++#endif ++ } ++ if (compat53_skipcomment(&lf, &c)) /* read initial portion */ ++ lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ ++ if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ ++#if defined(_MSC_VER) ++ if (freopen_s(&lf.f, filename, "rb", lf.f) != 0) ++ return compat53_errfile(L, "reopen", fnameindex); ++#else ++ lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ ++ if (lf.f == NULL) return compat53_errfile(L, "reopen", fnameindex); ++#endif ++ compat53_skipcomment(&lf, &c); /* re-read initial portion */ ++ } ++ if (c != EOF) ++ lf.buff[lf.n++] = (char)c; /* 'c' is the first character of the stream */ ++ status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1), mode); ++ readstatus = ferror(lf.f); ++ if (filename) fclose(lf.f); /* close file (even in case of errors) */ ++ if (readstatus) { ++ lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ ++ return compat53_errfile(L, "read", fnameindex); ++ } ++ lua_remove(L, fnameindex); ++ return status; ++} ++ ++ ++COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) { ++ int status = LUA_OK; ++ if (sz > 0 && buff[0] == LUA_SIGNATURE[0]) { ++ status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX); ++ } ++ else { ++ status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX); ++ } ++ if (status != LUA_OK) ++ return status; ++ return luaL_loadbuffer(L, buff, sz, name); ++} ++ ++ + #if !defined(l_inspectstat) && \ + (defined(unix) || defined(__unix) || defined(__unix__) || \ +- defined(__TOS_AIX__) || defined(_SYSTYPE_BSD)) ++ defined(__TOS_AIX__) || defined(_SYSTYPE_BSD) || \ ++ (defined(__APPLE__) && defined(__MACH__))) + /* some form of unix; check feature macros in unistd.h for details */ + # include + /* check posix version; the relevant include files and macros probably +@@ -414,7 +645,6 @@ COMPAT53_API int luaL_execresult (lua_St + return 3; + } + } +-#endif /* not COMPAT53_IS_LUAJIT */ + + + COMPAT53_API void luaL_buffinit (lua_State *L, luaL_Buffer_53 *B) { +@@ -501,6 +731,22 @@ COMPAT53_API int lua_isinteger (lua_Stat + } + + ++COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum) { ++ int ok = 0; ++ lua_Number n = lua_tonumberx(L, i, &ok); ++ if (ok) { ++ if (n == (lua_Integer)n) { ++ if (isnum) ++ *isnum = 1; ++ return (lua_Integer)n; ++ } ++ } ++ if (isnum) ++ *isnum = 0; ++ return 0; ++} ++ ++ + static void compat53_reverse (lua_State *L, int a, int b) { + for (; a < b; ++a, --b) { + lua_pushvalue(L, a); +@@ -537,7 +783,7 @@ COMPAT53_API void lua_seti (lua_State *L + + + #if !defined(lua_str2number) +-# define lua_str2number(s, p) strtod(s, p) ++# define lua_str2number(s, p) strtod((s), (p)) + #endif + + COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s) { +@@ -555,6 +801,40 @@ COMPAT53_API size_t lua_stringtonumber ( + } + + ++COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { ++ if (!luaL_callmeta(L, idx, "__tostring")) { ++ int t = lua_type(L, idx), tt = 0; ++ char const* name = NULL; ++ switch (t) { ++ case LUA_TNIL: ++ lua_pushliteral(L, "nil"); ++ break; ++ case LUA_TSTRING: ++ case LUA_TNUMBER: ++ lua_pushvalue(L, idx); ++ break; ++ case LUA_TBOOLEAN: ++ if (lua_toboolean(L, idx)) ++ lua_pushliteral(L, "true"); ++ else ++ lua_pushliteral(L, "false"); ++ break; ++ default: ++ tt = luaL_getmetafield(L, idx, "__name"); ++ name = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : lua_typename(L, t); ++ lua_pushfstring(L, "%s: %p", name, lua_topointer(L, idx)); ++ if (tt != LUA_TNIL) ++ lua_replace(L, -2); ++ break; ++ } ++ } else { ++ if (!lua_isstring(L, -1)) ++ luaL_error(L, "'__tostring' must return a string"); ++ } ++ return lua_tolstring(L, -1, len); ++} ++ ++ + COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, + lua_CFunction openf, int glb) { + luaL_checkstack(L, 3, "not enough stack slots available"); +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/c-api/compat-5.3.h luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/c-api/compat-5.3.h +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/c-api/compat-5.3.h 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/c-api/compat-5.3.h 2019-02-13 11:53:29.078405237 +0100 +@@ -4,16 +4,18 @@ + #include + #include + #include +-#if defined( __cplusplus ) && !defined( COMPAT53_LUA_CPP ) ++#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) + extern "C" { + #endif + #include + #include +-#if defined( __cplusplus ) && !defined( COMPAT53_LUA_CPP ) ++#include ++#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) + } + #endif + + ++#undef COMPAT53_INCLUDE_SOURCE + #if defined(COMPAT53_PREFIX) + /* - change the symbol names of functions to avoid linker conflicts + * - compat-5.3.c needs to be compiled (and linked) separately +@@ -21,13 +23,11 @@ extern "C" { + # if !defined(COMPAT53_API) + # define COMPAT53_API extern + # endif +-# undef COMPAT53_INCLUDE_SOURCE + #else /* COMPAT53_PREFIX */ + /* - make all functions static and include the source. +- * - don't mess with the symbol names of functions + * - compat-5.3.c doesn't need to be compiled (and linked) separately + */ +-# define COMPAT53_PREFIX lua ++# define COMPAT53_PREFIX compat53 + # undef COMPAT53_API + # if defined(__GNUC__) || defined(__clang__) + # define COMPAT53_API __attribute__((__unused__)) static +@@ -51,29 +51,54 @@ extern "C" { + * lua_upvaluejoin + * lua_version + * lua_yieldk +- * luaL_loadbufferx +- * luaL_loadfilex + */ + +-/* PUC-Rio Lua uses lconfig_h as include guard for luaconf.h, +- * LuaJIT uses luaconf_h. If you use PUC-Rio's include files +- * but LuaJIT's library, you will need to define the macro +- * COMPAT53_IS_LUAJIT yourself! */ +-#if !defined(COMPAT53_IS_LUAJIT) && defined(luaconf_h) +-# define COMPAT53_IS_LUAJIT +-#endif +- +-#define LUA_OK 0 +-#define LUA_OPADD 0 +-#define LUA_OPSUB 1 +-#define LUA_OPMUL 2 +-#define LUA_OPDIV 3 +-#define LUA_OPMOD 4 +-#define LUA_OPPOW 5 +-#define LUA_OPUNM 6 +-#define LUA_OPEQ 0 +-#define LUA_OPLT 1 +-#define LUA_OPLE 2 ++#ifndef LUA_OK ++# define LUA_OK 0 ++#endif ++#ifndef LUA_OPADD ++# define LUA_OPADD 0 ++#endif ++#ifndef LUA_OPSUB ++# define LUA_OPSUB 1 ++#endif ++#ifndef LUA_OPMUL ++# define LUA_OPMUL 2 ++#endif ++#ifndef LUA_OPDIV ++# define LUA_OPDIV 3 ++#endif ++#ifndef LUA_OPMOD ++# define LUA_OPMOD 4 ++#endif ++#ifndef LUA_OPPOW ++# define LUA_OPPOW 5 ++#endif ++#ifndef LUA_OPUNM ++# define LUA_OPUNM 6 ++#endif ++#ifndef LUA_OPEQ ++# define LUA_OPEQ 0 ++#endif ++#ifndef LUA_OPLT ++# define LUA_OPLT 1 ++#endif ++#ifndef LUA_OPLE ++# define LUA_OPLE 2 ++#endif ++ ++/* LuaJIT/Lua 5.1 does not have the updated ++ * error codes for thread status/function returns (but some patched versions do) ++ * define it only if it's not found ++ */ ++#if !defined(LUA_ERRGCMM) ++/* Use + 2 because in some versions of Lua (Lua 5.1) ++ * LUA_ERRFILE is defined as (LUA_ERRERR+1) ++ * so we need to avoid it (LuaJIT might have something at this ++ * integer value too) ++ */ ++# define LUA_ERRGCMM (LUA_ERRERR + 2) ++#endif /* LUA_ERRGCMM define */ + + typedef size_t lua_Unsigned; + +@@ -86,6 +111,14 @@ typedef struct luaL_Buffer_53 { + } luaL_Buffer_53; + #define luaL_Buffer luaL_Buffer_53 + ++/* In PUC-Rio 5.1, userdata is a simple FILE* ++ * In LuaJIT, it's a struct where the first member is a FILE* ++ * We can't support the `closef` member ++ */ ++typedef struct luaL_Stream { ++ FILE *f; ++} luaL_Stream; ++ + #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex) + COMPAT53_API int lua_absindex (lua_State *L, int i); + +@@ -99,20 +132,30 @@ COMPAT53_API int lua_compare (lua_State + COMPAT53_API void lua_copy (lua_State *L, int from, int to); + + #define lua_getuservalue(L, i) \ +- (lua_getfenv(L, i), lua_type(L, -1)) ++ (lua_getfenv((L), (i)), lua_type((L), -1)) + #define lua_setuservalue(L, i) \ +- (luaL_checktype(L, -1, LUA_TTABLE), lua_setfenv(L, i)) ++ (luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i))) + + #define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len) + COMPAT53_API void lua_len (lua_State *L, int i); + +-#define luaL_newlibtable(L, l) \ +- (lua_createtable(L, 0, sizeof(l)/sizeof(*(l))-1)) +-#define luaL_newlib(L, l) \ +- (luaL_newlibtable(L, l), luaL_register(L, NULL, l)) ++#define lua_pushstring(L, s) \ ++ (lua_pushstring((L), (s)), lua_tostring((L), -1)) ++ ++#define lua_pushlstring(L, s, len) \ ++ ((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1)) ++ ++#ifndef luaL_newlibtable ++# define luaL_newlibtable(L, l) \ ++ (lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1)) ++#endif ++#ifndef luaL_newlib ++# define luaL_newlib(L, l) \ ++ (luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l))) ++#endif + + #define lua_pushglobaltable(L) \ +- lua_pushvalue(L, LUA_GLOBALSINDEX) ++ lua_pushvalue((L), LUA_GLOBALSINDEX) + + #define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp) + COMPAT53_API int lua_rawgetp (lua_State *L, int i, const void *p); +@@ -120,10 +163,9 @@ COMPAT53_API int lua_rawgetp (lua_State + #define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp) + COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p); + +-#define lua_rawlen(L, i) lua_objlen(L, i) ++#define lua_rawlen(L, i) lua_objlen((L), (i)) + +-#define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx) +-COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum); ++#define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL) + + #define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx) + COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum); +@@ -131,6 +173,15 @@ COMPAT53_API lua_Number lua_tonumberx (l + #define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion) + COMPAT53_API void luaL_checkversion (lua_State *L); + ++#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53) ++COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode); ++ ++#define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex) ++COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode); ++ ++#define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx) ++COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); ++ + #define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53) + COMPAT53_API void luaL_checkstack (lua_State *L, int sp, const char *msg); + +@@ -138,7 +189,7 @@ COMPAT53_API void luaL_checkstack (lua_S + COMPAT53_API int luaL_getsubtable (lua_State* L, int i, const char *name); + + #define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len) +-COMPAT53_API int luaL_len (lua_State *L, int i); ++COMPAT53_API lua_Integer luaL_len (lua_State *L, int i); + + #define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs) + COMPAT53_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup); +@@ -149,10 +200,6 @@ COMPAT53_API void luaL_setmetatable (lua + #define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata) + COMPAT53_API void *luaL_testudata (lua_State *L, int i, const char *tname); + +-#define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring) +-COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len); +- +-#if !defined(COMPAT53_IS_LUAJIT) + #define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback) + COMPAT53_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level); + +@@ -161,12 +208,14 @@ COMPAT53_API int luaL_fileresult (lua_St + + #define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult) + COMPAT53_API int luaL_execresult (lua_State *L, int stat); +-#endif /* COMPAT53_IS_LUAJIT */ + + #define lua_callk(L, na, nr, ctx, cont) \ +- ((void)(ctx), (void)(cont), lua_call(L, na, nr)) ++ ((void)(ctx), (void)(cont), lua_call((L), (na), (nr))) + #define lua_pcallk(L, na, nr, err, ctx, cont) \ +- ((void)(ctx), (void)(cont), lua_pcall(L, na, nr, err)) ++ ((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err))) ++ ++#define lua_resume(L, from, nargs) \ ++ ((void)(from), lua_resume((L), (nargs))) + + #define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53) + COMPAT53_API void luaL_buffinit (lua_State *L, luaL_Buffer_53 *B); +@@ -185,15 +234,15 @@ COMPAT53_API void luaL_pushresult (luaL_ + + #undef luaL_buffinitsize + #define luaL_buffinitsize(L, B, s) \ +- (luaL_buffinit(L, B), luaL_prepbuffsize(B, s)) ++ (luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s))) + + #undef luaL_prepbuffer + #define luaL_prepbuffer(B) \ +- luaL_prepbuffsize(B, LUAL_BUFFERSIZE) ++ luaL_prepbuffsize((B), LUAL_BUFFERSIZE) + + #undef luaL_addchar + #define luaL_addchar(B, c) \ +- ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize(B, 1)), \ ++ ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \ + ((B)->ptr[(B)->nelems++] = (c))) + + #undef luaL_addsize +@@ -202,23 +251,23 @@ COMPAT53_API void luaL_pushresult (luaL_ + + #undef luaL_addstring + #define luaL_addstring(B, s) \ +- luaL_addlstring(B, s, strlen(s)) ++ luaL_addlstring((B), (s), strlen((s))) + + #undef luaL_pushresultsize + #define luaL_pushresultsize(B, s) \ +- (luaL_addsize(B, s), luaL_pushresult(B)) ++ (luaL_addsize((B), (s)), luaL_pushresult((B))) + + #if defined(LUA_COMPAT_APIINTCASTS) + #define lua_pushunsigned(L, n) \ +- lua_pushinteger(L, (lua_Integer)(n)) ++ lua_pushinteger((L), (lua_Integer)(n)) + #define lua_tounsignedx(L, i, is) \ +- ((lua_Unsigned)lua_tointegerx(L, i, is)) ++ ((lua_Unsigned)lua_tointegerx((L), (i), (is))) + #define lua_tounsigned(L, i) \ +- lua_tounsignedx(L, i, NULL) ++ lua_tounsignedx((L), (i), NULL) + #define luaL_checkunsigned(L, a) \ +- ((lua_Unsigned)luaL_checkinteger(L, a)) ++ ((lua_Unsigned)luaL_checkinteger((L), (a))) + #define luaL_optunsigned(L, a, d) \ +- ((lua_Unsigned)luaL_optinteger(L, a, (lua_Integer)(d))) ++ ((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d))) + #endif + + #endif /* Lua 5.1 only */ +@@ -233,13 +282,13 @@ typedef int lua_KContext; + typedef int (*lua_KFunction)(lua_State *L, int status, lua_KContext ctx); + + #define lua_dump(L, w, d, s) \ +- ((void)(s), lua_dump(L, w, d)) ++ ((void)(s), lua_dump((L), (w), (d))) + + #define lua_getfield(L, i, k) \ +- (lua_getfield(L, i, k), lua_type(L, -1)) ++ (lua_getfield((L), (i), (k)), lua_type((L), -1)) + + #define lua_gettable(L, i) \ +- (lua_gettable(L, i), lua_type(L, -1)) ++ (lua_gettable((L), (i)), lua_type((L), -1)) + + #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti) + COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i); +@@ -247,14 +296,17 @@ COMPAT53_API int lua_geti (lua_State *L, + #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger) + COMPAT53_API int lua_isinteger (lua_State *L, int index); + ++#define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53) ++COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum); ++ + #define lua_numbertointeger(n, p) \ + ((*(p) = (lua_Integer)(n)), 1) + + #define lua_rawget(L, i) \ +- (lua_rawget(L, i), lua_type(L, -1)) ++ (lua_rawget((L), (i)), lua_type((L), -1)) + + #define lua_rawgeti(L, i, n) \ +- (lua_rawgeti(L, i, n), lua_type(L, -1)) ++ (lua_rawgeti((L), (i), (n)), lua_type((L), -1)) + + #define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate) + COMPAT53_API void lua_rotate (lua_State *L, int idx, int n); +@@ -265,11 +317,14 @@ COMPAT53_API void lua_seti (lua_State *L + #define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber) + COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s); + ++#define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring) ++COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len); ++ + #define luaL_getmetafield(L, o, e) \ +- (luaL_getmetafield(L, o, e) ? lua_type(L, -1) : LUA_TNIL) ++ (luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL) + + #define luaL_newmetatable(L, tn) \ +- (luaL_newmetatable(L, tn) ? (lua_pushstring(L, tn), lua_setfield(L, -2, "__name"), 1) : 0) ++ (luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0) + + #define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53) + COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, +@@ -290,13 +345,16 @@ COMPAT53_API void luaL_requiref (lua_Sta + */ + + #define lua_getglobal(L, n) \ +- (lua_getglobal(L, n), lua_type(L, -1)) ++ (lua_getglobal((L), (n)), lua_type((L), -1)) + + #define lua_getuservalue(L, i) \ +- (lua_getuservalue(L, i), lua_type(L, -1)) ++ (lua_getuservalue((L), (i)), lua_type((L), -1)) ++ ++#define lua_pushlstring(L, s, len) \ ++ (((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))) + + #define lua_rawgetp(L, i, p) \ +- (lua_rawgetp(L, i, p), lua_type(L, -1)) ++ (lua_rawgetp((L), (i), (p)), lua_type((L), -1)) + + #define LUA_KFUNCTION(_name) \ + static int (_name)(lua_State *L, int status, lua_KContext ctx); \ +@@ -308,30 +366,30 @@ COMPAT53_API void luaL_requiref (lua_Sta + static int (_name)(lua_State *L, int status, lua_KContext ctx) + + #define lua_pcallk(L, na, nr, err, ctx, cont) \ +- lua_pcallk(L, na, nr, err, ctx, cont ## _52) ++ lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52) + + #define lua_callk(L, na, nr, ctx, cont) \ +- lua_callk(L, na, nr, ctx, cont ## _52) ++ lua_callk((L), (na), (nr), (ctx), cont ## _52) + + #define lua_yieldk(L, nr, ctx, cont) \ +- lua_yieldk(L, nr, ctx, cont ## _52) ++ lua_yieldk((L), (nr), (ctx), cont ## _52) + + #ifdef lua_call + # undef lua_call + # define lua_call(L, na, nr) \ +- (lua_callk)(L, na, nr, 0, NULL) ++ (lua_callk)((L), (na), (nr), 0, NULL) + #endif + + #ifdef lua_pcall + # undef lua_pcall + # define lua_pcall(L, na, nr, err) \ +- (lua_pcallk)(L, na, nr, err, 0, NULL) ++ (lua_pcallk)((L), (na), (nr), (err), 0, NULL) + #endif + + #ifdef lua_yield + # undef lua_yield + # define lua_yield(L, nr) \ +- (lua_yieldk)(L, nr, 0, NULL) ++ (lua_yieldk)((L), (nr), 0, NULL) + #endif + + #endif /* Lua 5.2 only */ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/compat53/init.lua luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/compat53/init.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/compat53/init.lua 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/compat53/init.lua 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,373 @@ ++local lua_version = _VERSION:sub(-3) ++ ++ ++if lua_version < "5.3" then ++ ++ local _G, pairs, require, select, type = ++ _G, pairs, require, select, type ++ local debug, io = debug, io ++ local unpack = lua_version == "5.1" and unpack or table.unpack ++ ++ local M = require("compat53.module") ++ ++ -- select the most powerful getmetatable function available ++ local gmt = type(debug) == "table" and debug.getmetatable or ++ getmetatable or function() return false end ++ -- metatable for file objects from Lua's standard io library ++ local file_meta = gmt(io.stdout) ++ ++ ++ -- make '*' optional for file:read and file:lines ++ if type(file_meta) == "table" and type(file_meta.__index) == "table" then ++ ++ local function addasterisk(fmt) ++ if type(fmt) == "string" and fmt:sub(1, 1) ~= "*" then ++ return "*"..fmt ++ else ++ return fmt ++ end ++ end ++ ++ local file_lines = file_meta.__index.lines ++ file_meta.__index.lines = function(self, ...) ++ local n = select('#', ...) ++ for i = 1, n do ++ local a = select(i, ...) ++ local b = addasterisk(a) ++ -- as an optimization we only allocate a table for the ++ -- modified format arguments when we have a '*' somewhere ++ if a ~= b then ++ local args = { ... } ++ args[i] = b ++ for j = i+1, n do ++ args[j] = addasterisk(args[j]) ++ end ++ return file_lines(self, unpack(args, 1, n)) ++ end ++ end ++ return file_lines(self, ...) ++ end ++ ++ local file_read = file_meta.__index.read ++ file_meta.__index.read = function(self, ...) ++ local n = select('#', ...) ++ for i = 1, n do ++ local a = select(i, ...) ++ local b = addasterisk(a) ++ -- as an optimization we only allocate a table for the ++ -- modified format arguments when we have a '*' somewhere ++ if a ~= b then ++ local args = { ... } ++ args[i] = b ++ for j = i+1, n do ++ args[j] = addasterisk(args[j]) ++ end ++ return file_read(self, unpack(args, 1, n)) ++ end ++ end ++ return file_read(self, ...) ++ end ++ ++ end -- got a valid metatable for file objects ++ ++ ++ -- changes for Lua 5.1 only ++ if lua_version == "5.1" then ++ ++ -- cache globals ++ local error, pcall, rawset, setmetatable, tostring, xpcall = ++ error, pcall, rawset, setmetatable, tostring, xpcall ++ local coroutine, package, string = coroutine, package, string ++ local coroutine_resume = coroutine.resume ++ local coroutine_running = coroutine.running ++ local coroutine_status = coroutine.status ++ local coroutine_yield = coroutine.yield ++ local io_type = io.type ++ ++ ++ -- detect LuaJIT (including LUAJIT_ENABLE_LUA52COMPAT compilation flag) ++ local is_luajit = (string.dump(function() end) or ""):sub(1, 3) == "\027LJ" ++ local is_luajit52 = is_luajit and ++ #setmetatable({}, { __len = function() return 1 end }) == 1 ++ ++ ++ -- make package.searchers available as an alias for package.loaders ++ local p_index = { searchers = package.loaders } ++ setmetatable(package, { ++ __index = p_index, ++ __newindex = function(p, k, v) ++ if k == "searchers" then ++ rawset(p, "loaders", v) ++ p_index.searchers = v ++ else ++ rawset(p, k, v) ++ end ++ end ++ }) ++ ++ ++ if type(file_meta) == "table" and type(file_meta.__index) == "table" then ++ if not is_luajit then ++ local function helper(_, var_1, ...) ++ if var_1 == nil then ++ if (...) ~= nil then ++ error((...), 2) ++ end ++ end ++ return var_1, ... ++ end ++ ++ local function lines_iterator(st) ++ return helper(st, st.f:read(unpack(st, 1, st.n))) ++ end ++ ++ local file_write = file_meta.__index.write ++ file_meta.__index.write = function(self, ...) ++ local res, msg, errno = file_write(self, ...) ++ if res then ++ return self ++ else ++ return nil, msg, errno ++ end ++ end ++ ++ file_meta.__index.lines = function(self, ...) ++ if io_type(self) == "closed file" then ++ error("attempt to use a closed file", 2) ++ end ++ local st = { f=self, n=select('#', ...), ... } ++ for i = 1, st.n do ++ local t = type(st[i]) ++ if t == "string" then ++ local fmt = st[i]:match("^*?([aln])") ++ if not fmt then ++ error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) ++ end ++ st[i] = "*"..fmt ++ elseif t ~= "number" then ++ error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) ++ end ++ end ++ return lines_iterator, st ++ end ++ end -- not luajit ++ end -- file_meta valid ++ ++ ++ -- the (x)pcall implementations start a new coroutine internally ++ -- to allow yielding even in Lua 5.1. to allow for accurate ++ -- stack traces we keep track of the nested coroutine activations ++ -- in the weak tables below: ++ local weak_meta = { __mode = "kv" } ++ -- maps the internal pcall coroutines to the user coroutine that ++ -- *should* be running if pcall didn't use coroutines internally ++ local pcall_mainOf = setmetatable({}, weak_meta) ++ -- table that maps each running coroutine started by pcall to ++ -- the coroutine that resumed it (user coroutine *or* pcall ++ -- coroutine!) ++ local pcall_previous = setmetatable({}, weak_meta) ++ -- reverse of `pcall_mainOf`. maps a user coroutine to the ++ -- currently active pcall coroutine started within it ++ local pcall_callOf = setmetatable({}, weak_meta) ++ -- similar to `pcall_mainOf` but is used only while executing ++ -- the error handler of xpcall (thus no nesting is necessary!) ++ local xpcall_running = setmetatable({}, weak_meta) ++ ++ -- handle debug functions ++ if type(debug) == "table" then ++ local debug_getinfo = debug.getinfo ++ local debug_traceback = debug.traceback ++ ++ if not is_luajit then ++ local function calculate_trace_level(co, level) ++ if level ~= nil then ++ for out = 1, 1/0 do ++ local info = (co==nil) and debug_getinfo(out, "") or debug_getinfo(co, out, "") ++ if info == nil then ++ local max = out-1 ++ if level <= max then ++ return level ++ end ++ return nil, level-max ++ end ++ end ++ end ++ return 1 ++ end ++ ++ local stack_pattern = "\nstack traceback:" ++ local stack_replace = "" ++ function debug.traceback(co, msg, level) ++ local lvl ++ local nilmsg ++ if type(co) ~= "thread" then ++ co, msg, level = coroutine_running(), co, msg ++ end ++ if msg == nil then ++ msg = "" ++ nilmsg = true ++ elseif type(msg) ~= "string" then ++ return msg ++ end ++ if co == nil then ++ msg = debug_traceback(msg, level or 1) ++ else ++ local xpco = xpcall_running[co] ++ if xpco ~= nil then ++ lvl, level = calculate_trace_level(xpco, level) ++ if lvl then ++ msg = debug_traceback(xpco, msg, lvl) ++ else ++ msg = msg..stack_pattern ++ end ++ lvl, level = calculate_trace_level(co, level) ++ if lvl then ++ local trace = debug_traceback(co, "", lvl) ++ msg = msg..trace:gsub(stack_pattern, stack_replace) ++ end ++ else ++ co = pcall_callOf[co] or co ++ lvl, level = calculate_trace_level(co, level) ++ if lvl then ++ msg = debug_traceback(co, msg, lvl) ++ else ++ msg = msg..stack_pattern ++ end ++ end ++ co = pcall_previous[co] ++ while co ~= nil do ++ lvl, level = calculate_trace_level(co, level) ++ if lvl then ++ local trace = debug_traceback(co, "", lvl) ++ msg = msg..trace:gsub(stack_pattern, stack_replace) ++ end ++ co = pcall_previous[co] ++ end ++ end ++ if nilmsg then ++ msg = msg:gsub("^\n", "") ++ end ++ msg = msg:gsub("\n\t%(tail call%): %?", "\000") ++ msg = msg:gsub("\n\t%.%.%.\n", "\001\n") ++ msg = msg:gsub("\n\t%.%.%.$", "\001") ++ msg = msg:gsub("(%z+)\001(%z+)", function(some, other) ++ return "\n\t(..."..#some+#other.."+ tail call(s)...)" ++ end) ++ msg = msg:gsub("\001(%z+)", function(zeros) ++ return "\n\t(..."..#zeros.."+ tail call(s)...)" ++ end) ++ msg = msg:gsub("(%z+)\001", function(zeros) ++ return "\n\t(..."..#zeros.."+ tail call(s)...)" ++ end) ++ msg = msg:gsub("%z+", function(zeros) ++ return "\n\t(..."..#zeros.." tail call(s)...)" ++ end) ++ msg = msg:gsub("\001", function() ++ return "\n\t..." ++ end) ++ return msg ++ end ++ end -- is not luajit ++ end -- debug table available ++ ++ ++ if not is_luajit52 then ++ local coroutine_running52 = M.coroutine.running ++ function M.coroutine.running() ++ local co, ismain = coroutine_running52() ++ if ismain then ++ return co, true ++ else ++ return pcall_mainOf[co] or co, false ++ end ++ end ++ end ++ ++ if not is_luajit then ++ local function pcall_results(current, call, success, ...) ++ if coroutine_status(call) == "suspended" then ++ return pcall_results(current, call, coroutine_resume(call, coroutine_yield(...))) ++ end ++ if pcall_previous then ++ pcall_previous[call] = nil ++ local main = pcall_mainOf[call] ++ if main == current then current = nil end ++ pcall_callOf[main] = current ++ end ++ pcall_mainOf[call] = nil ++ return success, ... ++ end ++ ++ local function pcall_exec(current, call, ...) ++ local main = pcall_mainOf[current] or current ++ pcall_mainOf[call] = main ++ if pcall_previous then ++ pcall_previous[call] = current ++ pcall_callOf[main] = call ++ end ++ return pcall_results(current, call, coroutine_resume(call, ...)) ++ end ++ ++ local coroutine_create52 = M.coroutine.create ++ ++ local function pcall_coroutine(func) ++ if type(func) ~= "function" then ++ local callable = func ++ func = function (...) return callable(...) end ++ end ++ return coroutine_create52(func) ++ end ++ ++ function M.pcall(func, ...) ++ local current = coroutine_running() ++ if not current then return pcall(func, ...) end ++ return pcall_exec(current, pcall_coroutine(func), ...) ++ end ++ ++ local function xpcall_catch(current, call, msgh, success, ...) ++ if not success then ++ xpcall_running[current] = call ++ local ok, result = pcall(msgh, ...) ++ xpcall_running[current] = nil ++ if not ok then ++ return false, "error in error handling ("..tostring(result)..")" ++ end ++ return false, result ++ end ++ return true, ... ++ end ++ ++ function M.xpcall(f, msgh, ...) ++ local current = coroutine_running() ++ if not current then ++ local args, n = { ... }, select('#', ...) ++ return xpcall(function() return f(unpack(args, 1, n)) end, msgh) ++ end ++ local call = pcall_coroutine(f) ++ return xpcall_catch(current, call, msgh, pcall_exec(current, call, ...)) ++ end ++ end -- not luajit ++ ++ end -- lua 5.1 ++ ++ ++ -- handle exporting to global scope ++ local function extend_table(from, to) ++ if from ~= to then ++ for k,v in pairs(from) do ++ if type(v) == "table" and ++ type(to[k]) == "table" and ++ v ~= to[k] then ++ extend_table(v, to[k]) ++ else ++ to[k] = v ++ end ++ end ++ end ++ end ++ ++ extend_table(M, _G) ++ ++end -- lua < 5.3 ++ ++-- vi: set expandtab softtabstop=3 shiftwidth=3 : +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/compat53/module.lua luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/compat53/module.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/compat53/module.lua 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/compat53/module.lua 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,827 @@ ++local _G, _VERSION = _G, _VERSION ++local lua_version = _VERSION:sub(-3) ++ ++ ++local M = _G ++ ++if lua_version < "5.3" then ++ ++ -- cache globals in upvalues ++ local error, ipairs, pairs, pcall, require, select, setmetatable, type = ++ error, ipairs, pairs, pcall, require, select, setmetatable, type ++ local debug, io, math, package, string, table = ++ debug, io, math, package, string, table ++ local io_lines = io.lines ++ local io_read = io.read ++ local unpack = lua_version == "5.1" and unpack or table.unpack ++ ++ -- create module table ++ M = {} ++ local M_meta = { ++ __index = _G, ++ -- __newindex is set at the end ++ } ++ setmetatable(M, M_meta) ++ ++ -- create subtables ++ M.io = setmetatable({}, { __index = io }) ++ M.math = setmetatable({}, { __index = math }) ++ M.string = setmetatable({}, { __index = string }) ++ M.table = setmetatable({}, { __index = table }) ++ M.utf8 = {} ++ ++ ++ -- select the most powerful getmetatable function available ++ local gmt = type(debug) == "table" and debug.getmetatable or ++ getmetatable or function() return false end ++ ++ -- type checking functions ++ local checkinteger -- forward declararation ++ ++ local function argcheck(cond, i, f, extra) ++ if not cond then ++ error("bad argument #"..i.." to '"..f.."' ("..extra..")", 0) ++ end ++ end ++ ++ ++ -- load utf8 library ++ local utf8_ok, utf8lib = pcall(require, "compat53.utf8") ++ if utf8_ok then ++ if lua_version == "5.1" then ++ utf8lib.charpattern = "[%z\1-\127\194-\244][\128-\191]*" ++ end ++ for k,v in pairs(utf8lib) do ++ M.utf8[k] = v ++ end ++ package.loaded["utf8"] = M.utf8 ++ end ++ ++ ++ -- load table library ++ local table_ok, tablib = pcall(require, "compat53.table") ++ if table_ok then ++ for k,v in pairs(tablib) do ++ M.table[k] = v ++ end ++ end ++ ++ ++ -- load string packing functions ++ local str_ok, strlib = pcall(require, "compat53.string") ++ if str_ok then ++ for k,v in pairs(strlib) do ++ M.string[k] = v ++ end ++ end ++ ++ ++ -- try Roberto's struct module for string packing/unpacking if ++ -- compat53.string is unavailable ++ if not str_ok then ++ local struct_ok, struct = pcall(require, "struct") ++ if struct_ok then ++ M.string.pack = struct.pack ++ M.string.packsize = struct.size ++ M.string.unpack = struct.unpack ++ end ++ end ++ ++ ++ -- update math library ++ do ++ local maxint, minint = 1 ++ ++ while maxint+1 > maxint and 2*maxint > maxint do ++ maxint = maxint * 2 ++ end ++ if 2*maxint <= maxint then ++ maxint = 2*maxint-1 ++ minint = -maxint-1 ++ else ++ maxint = maxint ++ minint = -maxint ++ end ++ M.math.maxinteger = maxint ++ M.math.mininteger = minint ++ ++ function M.math.tointeger(n) ++ if type(n) == "number" and n <= maxint and n >= minint and n % 1 == 0 then ++ return n ++ end ++ return nil ++ end ++ ++ function M.math.type(n) ++ if type(n) == "number" then ++ if n <= maxint and n >= minint and n % 1 == 0 then ++ return "integer" ++ else ++ return "float" ++ end ++ else ++ return nil ++ end ++ end ++ ++ function checkinteger(x, i, f) ++ local t = type(x) ++ if t ~= "number" then ++ error("bad argument #"..i.." to '"..f.. ++ "' (number expected, got "..t..")", 0) ++ elseif x > maxint or x < minint or x % 1 ~= 0 then ++ error("bad argument #"..i.." to '"..f.. ++ "' (number has no integer representation)", 0) ++ else ++ return x ++ end ++ end ++ ++ function M.math.ult(m, n) ++ m = checkinteger(m, "1", "math.ult") ++ n = checkinteger(n, "2", "math.ult") ++ if m >= 0 and n < 0 then ++ return true ++ elseif m < 0 and n >= 0 then ++ return false ++ else ++ return m < n ++ end ++ end ++ end ++ ++ ++ -- assert should allow non-string error objects ++ function M.assert(cond, ...) ++ if cond then ++ return cond, ... ++ elseif select('#', ...) > 0 then ++ error((...), 0) ++ else ++ error("assertion failed!", 0) ++ end ++ end ++ ++ ++ -- ipairs should respect __index metamethod ++ do ++ local function ipairs_iterator(st, var) ++ var = var + 1 ++ local val = st[var] ++ if val ~= nil then ++ return var, st[var] ++ end ++ end ++ function M.ipairs(t) ++ if gmt(t) ~= nil then -- t has metatable ++ return ipairs_iterator, t, 0 ++ else ++ return ipairs(t) ++ end ++ end ++ end ++ ++ ++ -- make '*' optional for io.read and io.lines ++ do ++ local function addasterisk(fmt) ++ if type(fmt) == "string" and fmt:sub(1, 1) ~= "*" then ++ return "*"..fmt ++ else ++ return fmt ++ end ++ end ++ ++ function M.io.read(...) ++ local n = select('#', ...) ++ for i = 1, n do ++ local a = select(i, ...) ++ local b = addasterisk(a) ++ -- as an optimization we only allocate a table for the ++ -- modified format arguments when we have a '*' somewhere. ++ if a ~= b then ++ local args = { ... } ++ args[i] = b ++ for j = i+1, n do ++ args[j] = addasterisk(args[j]) ++ end ++ return io_read(unpack(args, 1, n)) ++ end ++ end ++ return io_read(...) ++ end ++ ++ -- PUC-Rio Lua 5.1 uses a different implementation for io.lines! ++ function M.io.lines(...) ++ local n = select('#', ...) ++ for i = 2, n do ++ local a = select(i, ...) ++ local b = addasterisk(a) ++ -- as an optimization we only allocate a table for the ++ -- modified format arguments when we have a '*' somewhere. ++ if a ~= b then ++ local args = { ... } ++ args[i] = b ++ for j = i+1, n do ++ args[j] = addasterisk(args[j]) ++ end ++ return io_lines(unpack(args, 1, n)) ++ end ++ end ++ return io_lines(...) ++ end ++ end ++ ++ ++ -- update table library (if C module not available) ++ if not table_ok then ++ local table_concat = table.concat ++ local table_insert = table.insert ++ local table_remove = table.remove ++ local table_sort = table.sort ++ ++ function M.table.concat(list, sep, i, j) ++ local mt = gmt(list) ++ if type(mt) == "table" and type(mt.__len) == "function" then ++ local src = list ++ list, i, j = {}, i or 1, j or mt.__len(src) ++ for k = i, j do ++ list[k] = src[k] ++ end ++ end ++ return table_concat(list, sep, i, j) ++ end ++ ++ function M.table.insert(list, ...) ++ local mt = gmt(list) ++ local has_mt = type(mt) == "table" ++ local has_len = has_mt and type(mt.__len) == "function" ++ if has_mt and (has_len or mt.__index or mt.__newindex) then ++ local e = (has_len and mt.__len(list) or #list)+1 ++ local nargs, pos, value = select('#', ...), ... ++ if nargs == 1 then ++ pos, value = e, pos ++ elseif nargs == 2 then ++ pos = checkinteger(pos, "2", "table.insert") ++ argcheck(1 <= pos and pos <= e, "2", "table.insert", ++ "position out of bounds" ) ++ else ++ error("wrong number of arguments to 'insert'", 0) ++ end ++ for i = e-1, pos, -1 do ++ list[i+1] = list[i] ++ end ++ list[pos] = value ++ else ++ return table_insert(list, ...) ++ end ++ end ++ ++ function M.table.move(a1, f, e, t, a2) ++ a2 = a2 or a1 ++ f = checkinteger(f, "2", "table.move") ++ argcheck(f > 0, "2", "table.move", ++ "initial position must be positive") ++ e = checkinteger(e, "3", "table.move") ++ t = checkinteger(t, "4", "table.move") ++ if e >= f then ++ local m, n, d = 0, e-f, 1 ++ if t > f then m, n, d = n, m, -1 end ++ for i = m, n, d do ++ a2[t+i] = a1[f+i] ++ end ++ end ++ return a2 ++ end ++ ++ function M.table.remove(list, pos) ++ local mt = gmt(list) ++ local has_mt = type(mt) == "table" ++ local has_len = has_mt and type(mt.__len) == "function" ++ if has_mt and (has_len or mt.__index or mt.__newindex) then ++ local e = (has_len and mt.__len(list) or #list) ++ pos = pos ~= nil and checkinteger(pos, "2", "table.remove") or e ++ if pos ~= e then ++ argcheck(1 <= pos and pos <= e+1, "2", "table.remove", ++ "position out of bounds" ) ++ end ++ local result = list[pos] ++ while pos < e do ++ list[pos] = list[pos+1] ++ pos = pos + 1 ++ end ++ list[pos] = nil ++ return result ++ else ++ return table_remove(list, pos) ++ end ++ end ++ ++ do ++ local function pivot(list, cmp, a, b) ++ local m = b - a ++ if m > 2 then ++ local c = a + (m-m%2)/2 ++ local x, y, z = list[a], list[b], list[c] ++ if not cmp(x, y) then ++ x, y, a, b = y, x, b, a ++ end ++ if not cmp(y, z) then ++ y, b = z, c ++ end ++ if not cmp(x, y) then ++ y, b = x, a ++ end ++ return b, y ++ else ++ return b, list[b] ++ end ++ end ++ ++ local function lt_cmp(a, b) ++ return a < b ++ end ++ ++ local function qsort(list, cmp, b, e) ++ if b < e then ++ local i, j, k, val = b, e, pivot(list, cmp, b, e) ++ while i < j do ++ while i < j and cmp(list[i], val) do ++ i = i + 1 ++ end ++ while i < j and not cmp(list[j], val) do ++ j = j - 1 ++ end ++ if i < j then ++ list[i], list[j] = list[j], list[i] ++ if i == k then k = j end -- update pivot position ++ i, j = i+1, j-1 ++ end ++ end ++ if i ~= k and not cmp(list[i], val) then ++ list[i], list[k] = val, list[i] ++ k = i -- update pivot position ++ end ++ qsort(list, cmp, b, i == k and i-1 or i) ++ return qsort(list, cmp, i+1, e) ++ end ++ end ++ ++ function M.table.sort(list, cmp) ++ local mt = gmt(list) ++ local has_mt = type(mt) == "table" ++ local has_len = has_mt and type(mt.__len) == "function" ++ if has_len then ++ cmp = cmp or lt_cmp ++ local len = mt.__len(list) ++ return qsort(list, cmp, 1, len) ++ else ++ return table_sort(list, cmp) ++ end ++ end ++ end ++ ++ local function unpack_helper(list, i, j, ...) ++ if j < i then ++ return ... ++ else ++ return unpack_helper(list, i, j-1, list[j], ...) ++ end ++ end ++ function M.table.unpack(list, i, j) ++ local mt = gmt(list) ++ local has_mt = type(mt) == "table" ++ local has_len = has_mt and type(mt.__len) == "function" ++ if has_mt and (has_len or mt.__index) then ++ i, j = i or 1, j or (has_len and mt.__len(list)) or #list ++ return unpack_helper(list, i, j) ++ else ++ return unpack(list, i, j) ++ end ++ end ++ end -- update table library ++ ++ ++ -- bring Lua 5.1 (and LuaJIT) up to speed with Lua 5.2 ++ if lua_version == "5.1" then ++ -- detect LuaJIT (including LUAJIT_ENABLE_LUA52COMPAT compilation flag) ++ local is_luajit = (string.dump(function() end) or ""):sub(1, 3) == "\027LJ" ++ local is_luajit52 = is_luajit and ++ #setmetatable({}, { __len = function() return 1 end }) == 1 ++ ++ -- cache globals in upvalues ++ local load, loadfile, loadstring, setfenv, xpcall = ++ load, loadfile, loadstring, setfenv, xpcall ++ local coroutine, os = coroutine, os ++ local coroutine_create = coroutine.create ++ local coroutine_resume = coroutine.resume ++ local coroutine_running = coroutine.running ++ local coroutine_status = coroutine.status ++ local coroutine_yield = coroutine.yield ++ local io_input = io.input ++ local io_open = io.open ++ local io_output = io.output ++ local io_write = io.write ++ local math_log = math.log ++ local os_execute = os.execute ++ local string_find = string.find ++ local string_format = string.format ++ local string_gmatch = string.gmatch ++ local string_gsub = string.gsub ++ local string_match = string.match ++ local string_rep = string.rep ++ local table_concat = table.concat ++ ++ -- create subtables ++ M.coroutine = setmetatable({}, { __index = coroutine }) ++ M.os = setmetatable({}, { __index = os }) ++ M.package = setmetatable({}, { __index = package }) ++ ++ -- handle debug functions ++ if type(debug) == "table" then ++ local debug_setfenv = debug.setfenv ++ local debug_getfenv = debug.getfenv ++ local debug_setmetatable = debug.setmetatable ++ ++ M.debug = setmetatable({}, { __index = debug }) ++ ++ if not is_luajit52 then ++ function M.debug.setuservalue(obj, value) ++ if type(obj) ~= "userdata" then ++ error("bad argument #1 to 'setuservalue' (userdata expected, got ".. ++ type(obj)..")", 2) ++ end ++ if value == nil then value = _G end ++ if type(value) ~= "table" then ++ error("bad argument #2 to 'setuservalue' (table expected, got ".. ++ type(value)..")", 2) ++ end ++ return debug_setfenv(obj, value) ++ end ++ ++ function M.debug.getuservalue(obj) ++ if type(obj) ~= "userdata" then ++ return nil ++ else ++ local v = debug_getfenv(obj) ++ if v == _G or v == package then ++ return nil ++ end ++ return v ++ end ++ end ++ ++ function M.debug.setmetatable(value, tab) ++ debug_setmetatable(value, tab) ++ return value ++ end ++ end -- not luajit with compat52 enabled ++ end -- debug table available ++ ++ ++ if not is_luajit52 then ++ function M.pairs(t) ++ local mt = gmt(t) ++ if type(mt) == "table" and type(mt.__pairs) == "function" then ++ return mt.__pairs(t) ++ else ++ return pairs(t) ++ end ++ end ++ end ++ ++ ++ if not is_luajit then ++ local function check_mode(mode, prefix) ++ local has = { text = false, binary = false } ++ for i = 1,#mode do ++ local c = mode:sub(i, i) ++ if c == "t" then has.text = true end ++ if c == "b" then has.binary = true end ++ end ++ local t = prefix:sub(1, 1) == "\27" and "binary" or "text" ++ if not has[t] then ++ return "attempt to load a "..t.." chunk (mode is '"..mode.."')" ++ end ++ end ++ ++ function M.load(ld, source, mode, env) ++ mode = mode or "bt" ++ local chunk, msg ++ if type( ld ) == "string" then ++ if mode ~= "bt" then ++ local merr = check_mode(mode, ld) ++ if merr then return nil, merr end ++ end ++ chunk, msg = loadstring(ld, source) ++ else ++ local ld_type = type(ld) ++ if ld_type ~= "function" then ++ error("bad argument #1 to 'load' (function expected, got ".. ++ ld_type..")", 2) ++ end ++ if mode ~= "bt" then ++ local checked, merr = false, nil ++ local function checked_ld() ++ if checked then ++ return ld() ++ else ++ checked = true ++ local v = ld() ++ merr = check_mode(mode, v or "") ++ if merr then return nil end ++ return v ++ end ++ end ++ chunk, msg = load(checked_ld, source) ++ if merr then return nil, merr end ++ else ++ chunk, msg = load(ld, source) ++ end ++ end ++ if not chunk then ++ return chunk, msg ++ end ++ if env ~= nil then ++ setfenv(chunk, env) ++ end ++ return chunk ++ end ++ ++ M.loadstring = M.load ++ ++ function M.loadfile(file, mode, env) ++ mode = mode or "bt" ++ if mode ~= "bt" then ++ local f = io_open(file, "rb") ++ if f then ++ local prefix = f:read(1) ++ f:close() ++ if prefix then ++ local merr = check_mode(mode, prefix) ++ if merr then return nil, merr end ++ end ++ end ++ end ++ local chunk, msg = loadfile(file) ++ if not chunk then ++ return chunk, msg ++ end ++ if env ~= nil then ++ setfenv(chunk, env) ++ end ++ return chunk ++ end ++ end -- not luajit ++ ++ ++ if not is_luajit52 then ++ function M.rawlen(v) ++ local t = type(v) ++ if t ~= "string" and t ~= "table" then ++ error("bad argument #1 to 'rawlen' (table or string expected)", 2) ++ end ++ return #v ++ end ++ end ++ ++ ++ if not is_luajit then ++ function M.xpcall(f, msgh, ...) ++ local args, n = { ... }, select('#', ...) ++ return xpcall(function() return f(unpack(args, 1, n)) end, msgh) ++ end ++ end ++ ++ ++ if not is_luajit52 then ++ function M.os.execute(cmd) ++ local code = os_execute(cmd) ++ -- Lua 5.1 does not report exit by signal. ++ if code == 0 then ++ return true, "exit", code ++ else ++ if package.config:sub(1, 1) == '/' then ++ code = code/256 -- only correct on Linux! ++ end ++ return nil, "exit", code ++ end ++ end ++ end ++ ++ ++ if not table_ok and not is_luajit52 then ++ M.table.pack = function(...) ++ return { n = select('#', ...), ... } ++ end ++ end ++ ++ ++ local main_coroutine = coroutine_create(function() end) ++ ++ function M.coroutine.create(func) ++ local success, result = pcall(coroutine_create, func) ++ if not success then ++ if type(func) ~= "function" then ++ error("bad argument #1 (function expected)", 0) ++ end ++ result = coroutine_create(function(...) return func(...) end) ++ end ++ return result ++ end ++ ++ if not is_luajit52 then ++ function M.coroutine.running() ++ local co = coroutine_running() ++ if co then ++ return co, false ++ else ++ return main_coroutine, true ++ end ++ end ++ end ++ ++ function M.coroutine.yield(...) ++ local co, flag = coroutine_running() ++ if co and not flag then ++ return coroutine_yield(...) ++ else ++ error("attempt to yield from outside a coroutine", 0) ++ end ++ end ++ ++ if not is_luajit then ++ function M.coroutine.resume(co, ...) ++ if co == main_coroutine then ++ return false, "cannot resume non-suspended coroutine" ++ else ++ return coroutine_resume(co, ...) ++ end ++ end ++ ++ function M.coroutine.status(co) ++ local notmain = coroutine_running() ++ if co == main_coroutine then ++ return notmain and "normal" or "running" ++ else ++ return coroutine_status(co) ++ end ++ end ++ end -- not luajit ++ ++ ++ if not is_luajit then ++ M.math.log = function(x, base) ++ if base ~= nil then ++ return math_log(x)/math_log(base) ++ else ++ return math_log(x) ++ end ++ end ++ end ++ ++ ++ if not is_luajit then ++ function M.package.searchpath(name, path, sep, rep) ++ sep = (sep or "."):gsub("(%p)", "%%%1") ++ rep = (rep or package.config:sub(1, 1)):gsub("(%%)", "%%%1") ++ local pname = name:gsub(sep, rep):gsub("(%%)", "%%%1") ++ local msg = {} ++ for subpath in path:gmatch("[^;]+") do ++ local fpath = subpath:gsub("%?", pname) ++ local f = io_open(fpath, "r") ++ if f then ++ f:close() ++ return fpath ++ end ++ msg[#msg+1] = "\n\tno file '" .. fpath .. "'" ++ end ++ return nil, table_concat(msg) ++ end ++ end ++ ++ ++ local function fix_pattern(pattern) ++ return (string_gsub(pattern, "%z", "%%z")) ++ end ++ ++ function M.string.find(s, pattern, ...) ++ return string_find(s, fix_pattern(pattern), ...) ++ end ++ ++ function M.string.gmatch(s, pattern) ++ return string_gmatch(s, fix_pattern(pattern)) ++ end ++ ++ function M.string.gsub(s, pattern, ...) ++ return string_gsub(s, fix_pattern(pattern), ...) ++ end ++ ++ function M.string.match(s, pattern, ...) ++ return string_match(s, fix_pattern(pattern), ...) ++ end ++ ++ if not is_luajit then ++ function M.string.rep(s, n, sep) ++ if sep ~= nil and sep ~= "" and n >= 2 then ++ return s .. string_rep(sep..s, n-1) ++ else ++ return string_rep(s, n) ++ end ++ end ++ end ++ ++ if not is_luajit then ++ do ++ local addqt = { ++ ["\n"] = "\\\n", ++ ["\\"] = "\\\\", ++ ["\""] = "\\\"" ++ } ++ ++ local function addquoted(c, d) ++ return (addqt[c] or string_format(d~="" and "\\%03d" or "\\%d", c:byte()))..d ++ end ++ ++ function M.string.format(fmt, ...) ++ local args, n = { ... }, select('#', ...) ++ local i = 0 ++ local function adjust_fmt(lead, mods, kind) ++ if #lead % 2 == 0 then ++ i = i + 1 ++ if kind == "s" then ++ args[i] = _G.tostring(args[i]) ++ elseif kind == "q" then ++ args[i] = '"'..string_gsub(args[i], "([%z%c\\\"\n])(%d?)", addquoted)..'"' ++ return lead.."%"..mods.."s" ++ end ++ end ++ end ++ fmt = string_gsub(fmt, "(%%*)%%([%d%.%-%+%# ]*)(%a)", adjust_fmt) ++ return string_format(fmt, unpack(args, 1, n)) ++ end ++ end ++ end ++ ++ ++ function M.io.write(...) ++ local res, msg, errno = io_write(...) ++ if res then ++ return io_output() ++ else ++ return nil, msg, errno ++ end ++ end ++ ++ if not is_luajit then ++ local function helper(st, var_1, ...) ++ if var_1 == nil then ++ if st.doclose then st.f:close() end ++ if (...) ~= nil then ++ error((...), 2) ++ end ++ end ++ return var_1, ... ++ end ++ ++ local function lines_iterator(st) ++ return helper(st, st.f:read(unpack(st, 1, st.n))) ++ end ++ ++ function M.io.lines(fname, ...) ++ local doclose, file, msg ++ if fname ~= nil then ++ doclose, file, msg = true, io_open(fname, "r") ++ if not file then error(msg, 2) end ++ else ++ doclose, file = false, io_input() ++ end ++ local st = { f=file, doclose=doclose, n=select('#', ...), ... } ++ for i = 1, st.n do ++ local t = type(st[i]) ++ if t == "string" then ++ local fmt = st[i]:match("^%*?([aln])") ++ if not fmt then ++ error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) ++ end ++ st[i] = "*"..fmt ++ elseif t ~= "number" then ++ error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) ++ end ++ end ++ return lines_iterator, st ++ end ++ end -- not luajit ++ ++ end -- lua 5.1 ++ ++ -- further write should be forwarded to _G ++ M_meta.__newindex = _G ++ ++end -- lua < 5.3 ++ ++ ++-- return module table ++return M ++ ++-- vi: set expandtab softtabstop=3 shiftwidth=3 : +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/LICENSE luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/LICENSE +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/LICENSE 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/LICENSE 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,20 @@ ++The MIT License (MIT) ++ ++Copyright (c) 2015 Kepler Project. ++ ++Permission is hereby granted, free of charge, to any person obtaining a copy of ++this software and associated documentation files (the "Software"), to deal in ++the Software without restriction, including without limitation the rights to ++use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ++the Software, and to permit persons to whom the Software is furnished to do so, ++subject to the following conditions: ++ ++The above copyright notice and this permission notice shall be included in all ++copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ++FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ++COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ++IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/lprefix.h luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/lprefix.h +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/lprefix.h 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/lprefix.h 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,175 @@ ++/* ++** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ ++** Definitions for Lua code that must come before any other header file ++** See Copyright Notice in lua.h ++*/ ++ ++#ifndef lprefix_h ++#define lprefix_h ++ ++ ++/* ++** Allows POSIX/XSI stuff ++*/ ++#if !defined(LUA_USE_C89) /* { */ ++ ++#if !defined(_XOPEN_SOURCE) ++#define _XOPEN_SOURCE 600 ++#elif _XOPEN_SOURCE == 0 ++#undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ ++#endif ++ ++/* ++** Allows manipulation of large files in gcc and some other compilers ++*/ ++#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) ++#define _LARGEFILE_SOURCE 1 ++#define _FILE_OFFSET_BITS 64 ++#endif ++ ++#endif /* } */ ++ ++ ++/* ++** Windows stuff ++*/ ++#if defined(_WIN32) /* { */ ++ ++#if !defined(_CRT_SECURE_NO_WARNINGS) ++#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ ++#endif ++ ++#endif /* } */ ++ ++ ++/* COMPAT53 adaptation */ ++#include "c-api/compat-5.3.h" ++ ++#undef LUAMOD_API ++#define LUAMOD_API extern ++ ++ ++#ifdef lutf8lib_c ++# define luaopen_utf8 luaopen_compat53_utf8 ++/* we don't support the %U format string of lua_pushfstring! ++ * code below adapted from the Lua 5.3 sources: ++ */ ++static const char *compat53_utf8_escape (lua_State* L, long x) { ++ if (x < 0x80) { /* ASCII */ ++ char c = (char)x; ++ lua_pushlstring(L, &c, 1); ++ } else { ++ char buff[8] = { 0 }; ++ unsigned int mfb = 0x3f; ++ int n = 1; ++ do { ++ buff[8 - (n++)] = (char)(0x80|(x & 0x3f)); ++ x >>= 6; ++ mfb >>= 1; ++ } while (x > mfb); ++ buff[8-n] = (char)((~mfb << 1) | x); ++ lua_pushlstring(L, buff+8-n, n); ++ } ++ return lua_tostring(L, -1); ++} ++# define lua_pushfstring(L, fmt, l) \ ++ compat53_utf8_escape(L, l) ++#endif ++ ++ ++#ifdef ltablib_c ++# define luaopen_table luaopen_compat53_table ++# ifndef LUA_MAXINTEGER ++/* conservative estimate: */ ++# define LUA_MAXINTEGER INT_MAX ++# endif ++#endif /* ltablib_c */ ++ ++ ++#ifdef lstrlib_c ++#include ++#include ++/* move the string library open function out of the way (we only take ++ * the string packing functions)! ++ */ ++# define luaopen_string luaopen_string_XXX ++/* used in string.format implementation, which we don't use: */ ++# ifndef LUA_INTEGER_FRMLEN ++# define LUA_INTEGER_FRMLEN "" ++# define LUA_NUMBER_FRMLEN "" ++# endif ++# ifndef LUA_MININTEGER ++# define LUA_MININTEGER 0 ++# endif ++# ifndef LUA_INTEGER_FMT ++# define LUA_INTEGER_FMT "%d" ++# endif ++# ifndef LUAI_UACINT ++# define LUAI_UACINT lua_Integer ++# endif ++/* different Lua 5.3 versions have conflicting variants of this macro ++ * in luaconf.h, there's a fallback implementation in lstrlib.c, and ++ * the macro isn't used for string (un)packing anyway! ++ * */ ++# undef lua_number2strx ++# if LUA_VERSION_NUM < 503 ++/* lstrlib assumes that lua_Integer and lua_Unsigned have the same ++ * size, so we use the unsigned equivalent of ptrdiff_t! */ ++# define lua_Unsigned size_t ++# endif ++# ifndef l_mathlim ++# ifdef LUA_NUMBER_DOUBLE ++# define l_mathlim(n) (DBL_##n) ++# else ++# define l_mathlim(n) (FLT_##n) ++# endif ++# endif ++# ifndef l_mathop ++# ifdef LUA_NUMBER_DOUBLE ++# define l_mathop(op) op ++# else ++# define l_mathop(op) op##f ++# endif ++# endif ++# ifndef lua_getlocaledecpoint ++# define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) ++# endif ++# ifndef l_sprintf ++# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L ++# define l_sprintf(s,sz,f,i) (snprintf(s, sz, f, i)) ++# else ++# define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s, f, i)) ++# endif ++# endif ++ ++static int str_pack (lua_State *L); ++static int str_packsize (lua_State *L); ++static int str_unpack (lua_State *L); ++LUAMOD_API int luaopen_compat53_string (lua_State *L) { ++ luaL_Reg const funcs[] = { ++ { "pack", str_pack }, ++ { "packsize", str_packsize }, ++ { "unpack", str_unpack }, ++ { NULL, NULL } ++ }; ++ luaL_newlib(L, funcs); ++ return 1; ++} ++/* fake CLANG feature detection on other compilers */ ++# ifndef __has_attribute ++# define __has_attribute(x) 0 ++# endif ++/* make luaopen_string(_XXX) static, so it (and all other referenced ++ * string functions) won't be included in the resulting dll ++ * (hopefully). ++ */ ++# undef LUAMOD_API ++# if defined(__GNUC__) || __has_attribute(__unused__) ++# define LUAMOD_API __attribute__((__unused__)) static ++# else ++# define LUAMOD_API static ++# endif ++#endif /* lstrlib.c */ ++ ++#endif ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/lstrlib.c luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/lstrlib.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/lstrlib.c 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/lstrlib.c 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,1584 @@ ++/* ++** $Id: lstrlib.c,v 1.254 2016/12/22 13:08:50 roberto Exp $ ++** Standard library for string operations and pattern-matching ++** See Copyright Notice in lua.h ++*/ ++ ++#define lstrlib_c ++#define LUA_LIB ++ ++#include "lprefix.h" ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "lua.h" ++ ++#include "lauxlib.h" ++#include "lualib.h" ++ ++ ++/* ++** maximum number of captures that a pattern can do during ++** pattern-matching. This limit is arbitrary, but must fit in ++** an unsigned char. ++*/ ++#if !defined(LUA_MAXCAPTURES) ++#define LUA_MAXCAPTURES 32 ++#endif ++ ++ ++/* macro to 'unsign' a character */ ++#define uchar(c) ((unsigned char)(c)) ++ ++ ++/* ++** Some sizes are better limited to fit in 'int', but must also fit in ++** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) ++*/ ++#define MAX_SIZET ((size_t)(~(size_t)0)) ++ ++#define MAXSIZE \ ++ (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX)) ++ ++ ++ ++ ++static int str_len (lua_State *L) { ++ size_t l; ++ luaL_checklstring(L, 1, &l); ++ lua_pushinteger(L, (lua_Integer)l); ++ return 1; ++} ++ ++ ++/* translate a relative string position: negative means back from end */ ++static lua_Integer posrelat (lua_Integer pos, size_t len) { ++ if (pos >= 0) return pos; ++ else if (0u - (size_t)pos > len) return 0; ++ else return (lua_Integer)len + pos + 1; ++} ++ ++ ++static int str_sub (lua_State *L) { ++ size_t l; ++ const char *s = luaL_checklstring(L, 1, &l); ++ lua_Integer start = posrelat(luaL_checkinteger(L, 2), l); ++ lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l); ++ if (start < 1) start = 1; ++ if (end > (lua_Integer)l) end = l; ++ if (start <= end) ++ lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1); ++ else lua_pushliteral(L, ""); ++ return 1; ++} ++ ++ ++static int str_reverse (lua_State *L) { ++ size_t l, i; ++ luaL_Buffer b; ++ const char *s = luaL_checklstring(L, 1, &l); ++ char *p = luaL_buffinitsize(L, &b, l); ++ for (i = 0; i < l; i++) ++ p[i] = s[l - i - 1]; ++ luaL_pushresultsize(&b, l); ++ return 1; ++} ++ ++ ++static int str_lower (lua_State *L) { ++ size_t l; ++ size_t i; ++ luaL_Buffer b; ++ const char *s = luaL_checklstring(L, 1, &l); ++ char *p = luaL_buffinitsize(L, &b, l); ++ for (i=0; i MAXSIZE / n) /* may overflow? */ ++ return luaL_error(L, "resulting string too large"); ++ else { ++ size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; ++ luaL_Buffer b; ++ char *p = luaL_buffinitsize(L, &b, totallen); ++ while (n-- > 1) { /* first n-1 copies (followed by separator) */ ++ memcpy(p, s, l * sizeof(char)); p += l; ++ if (lsep > 0) { /* empty 'memcpy' is not that cheap */ ++ memcpy(p, sep, lsep * sizeof(char)); ++ p += lsep; ++ } ++ } ++ memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ ++ luaL_pushresultsize(&b, totallen); ++ } ++ return 1; ++} ++ ++ ++static int str_byte (lua_State *L) { ++ size_t l; ++ const char *s = luaL_checklstring(L, 1, &l); ++ lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l); ++ lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l); ++ int n, i; ++ if (posi < 1) posi = 1; ++ if (pose > (lua_Integer)l) pose = l; ++ if (posi > pose) return 0; /* empty interval; return no values */ ++ if (pose - posi >= INT_MAX) /* arithmetic overflow? */ ++ return luaL_error(L, "string slice too long"); ++ n = (int)(pose - posi) + 1; ++ luaL_checkstack(L, n, "string slice too long"); ++ for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) ++ return luaL_error(ms->L, "invalid capture index %%%d", l + 1); ++ return l; ++} ++ ++ ++static int capture_to_close (MatchState *ms) { ++ int level = ms->level; ++ for (level--; level>=0; level--) ++ if (ms->capture[level].len == CAP_UNFINISHED) return level; ++ return luaL_error(ms->L, "invalid pattern capture"); ++} ++ ++ ++static const char *classend (MatchState *ms, const char *p) { ++ switch (*p++) { ++ case L_ESC: { ++ if (p == ms->p_end) ++ luaL_error(ms->L, "malformed pattern (ends with '%%')"); ++ return p+1; ++ } ++ case '[': { ++ if (*p == '^') p++; ++ do { /* look for a ']' */ ++ if (p == ms->p_end) ++ luaL_error(ms->L, "malformed pattern (missing ']')"); ++ if (*(p++) == L_ESC && p < ms->p_end) ++ p++; /* skip escapes (e.g. '%]') */ ++ } while (*p != ']'); ++ return p+1; ++ } ++ default: { ++ return p; ++ } ++ } ++} ++ ++ ++static int match_class (int c, int cl) { ++ int res; ++ switch (tolower(cl)) { ++ case 'a' : res = isalpha(c); break; ++ case 'c' : res = iscntrl(c); break; ++ case 'd' : res = isdigit(c); break; ++ case 'g' : res = isgraph(c); break; ++ case 'l' : res = islower(c); break; ++ case 'p' : res = ispunct(c); break; ++ case 's' : res = isspace(c); break; ++ case 'u' : res = isupper(c); break; ++ case 'w' : res = isalnum(c); break; ++ case 'x' : res = isxdigit(c); break; ++ case 'z' : res = (c == 0); break; /* deprecated option */ ++ default: return (cl == c); ++ } ++ return (islower(cl) ? res : !res); ++} ++ ++ ++static int matchbracketclass (int c, const char *p, const char *ec) { ++ int sig = 1; ++ if (*(p+1) == '^') { ++ sig = 0; ++ p++; /* skip the '^' */ ++ } ++ while (++p < ec) { ++ if (*p == L_ESC) { ++ p++; ++ if (match_class(c, uchar(*p))) ++ return sig; ++ } ++ else if ((*(p+1) == '-') && (p+2 < ec)) { ++ p+=2; ++ if (uchar(*(p-2)) <= c && c <= uchar(*p)) ++ return sig; ++ } ++ else if (uchar(*p) == c) return sig; ++ } ++ return !sig; ++} ++ ++ ++static int singlematch (MatchState *ms, const char *s, const char *p, ++ const char *ep) { ++ if (s >= ms->src_end) ++ return 0; ++ else { ++ int c = uchar(*s); ++ switch (*p) { ++ case '.': return 1; /* matches any char */ ++ case L_ESC: return match_class(c, uchar(*(p+1))); ++ case '[': return matchbracketclass(c, p, ep-1); ++ default: return (uchar(*p) == c); ++ } ++ } ++} ++ ++ ++static const char *matchbalance (MatchState *ms, const char *s, ++ const char *p) { ++ if (p >= ms->p_end - 1) ++ luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); ++ if (*s != *p) return NULL; ++ else { ++ int b = *p; ++ int e = *(p+1); ++ int cont = 1; ++ while (++s < ms->src_end) { ++ if (*s == e) { ++ if (--cont == 0) return s+1; ++ } ++ else if (*s == b) cont++; ++ } ++ } ++ return NULL; /* string ends out of balance */ ++} ++ ++ ++static const char *max_expand (MatchState *ms, const char *s, ++ const char *p, const char *ep) { ++ ptrdiff_t i = 0; /* counts maximum expand for item */ ++ while (singlematch(ms, s + i, p, ep)) ++ i++; ++ /* keeps trying to match with the maximum repetitions */ ++ while (i>=0) { ++ const char *res = match(ms, (s+i), ep+1); ++ if (res) return res; ++ i--; /* else didn't match; reduce 1 repetition to try again */ ++ } ++ return NULL; ++} ++ ++ ++static const char *min_expand (MatchState *ms, const char *s, ++ const char *p, const char *ep) { ++ for (;;) { ++ const char *res = match(ms, s, ep+1); ++ if (res != NULL) ++ return res; ++ else if (singlematch(ms, s, p, ep)) ++ s++; /* try with one more repetition */ ++ else return NULL; ++ } ++} ++ ++ ++static const char *start_capture (MatchState *ms, const char *s, ++ const char *p, int what) { ++ const char *res; ++ int level = ms->level; ++ if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); ++ ms->capture[level].init = s; ++ ms->capture[level].len = what; ++ ms->level = level+1; ++ if ((res=match(ms, s, p)) == NULL) /* match failed? */ ++ ms->level--; /* undo capture */ ++ return res; ++} ++ ++ ++static const char *end_capture (MatchState *ms, const char *s, ++ const char *p) { ++ int l = capture_to_close(ms); ++ const char *res; ++ ms->capture[l].len = s - ms->capture[l].init; /* close capture */ ++ if ((res = match(ms, s, p)) == NULL) /* match failed? */ ++ ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ ++ return res; ++} ++ ++ ++static const char *match_capture (MatchState *ms, const char *s, int l) { ++ size_t len; ++ l = check_capture(ms, l); ++ len = ms->capture[l].len; ++ if ((size_t)(ms->src_end-s) >= len && ++ memcmp(ms->capture[l].init, s, len) == 0) ++ return s+len; ++ else return NULL; ++} ++ ++ ++static const char *match (MatchState *ms, const char *s, const char *p) { ++ if (ms->matchdepth-- == 0) ++ luaL_error(ms->L, "pattern too complex"); ++ init: /* using goto's to optimize tail recursion */ ++ if (p != ms->p_end) { /* end of pattern? */ ++ switch (*p) { ++ case '(': { /* start capture */ ++ if (*(p + 1) == ')') /* position capture? */ ++ s = start_capture(ms, s, p + 2, CAP_POSITION); ++ else ++ s = start_capture(ms, s, p + 1, CAP_UNFINISHED); ++ break; ++ } ++ case ')': { /* end capture */ ++ s = end_capture(ms, s, p + 1); ++ break; ++ } ++ case '$': { ++ if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */ ++ goto dflt; /* no; go to default */ ++ s = (s == ms->src_end) ? s : NULL; /* check end of string */ ++ break; ++ } ++ case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ ++ switch (*(p + 1)) { ++ case 'b': { /* balanced string? */ ++ s = matchbalance(ms, s, p + 2); ++ if (s != NULL) { ++ p += 4; goto init; /* return match(ms, s, p + 4); */ ++ } /* else fail (s == NULL) */ ++ break; ++ } ++ case 'f': { /* frontier? */ ++ const char *ep; char previous; ++ p += 2; ++ if (*p != '[') ++ luaL_error(ms->L, "missing '[' after '%%f' in pattern"); ++ ep = classend(ms, p); /* points to what is next */ ++ previous = (s == ms->src_init) ? '\0' : *(s - 1); ++ if (!matchbracketclass(uchar(previous), p, ep - 1) && ++ matchbracketclass(uchar(*s), p, ep - 1)) { ++ p = ep; goto init; /* return match(ms, s, ep); */ ++ } ++ s = NULL; /* match failed */ ++ break; ++ } ++ case '0': case '1': case '2': case '3': ++ case '4': case '5': case '6': case '7': ++ case '8': case '9': { /* capture results (%0-%9)? */ ++ s = match_capture(ms, s, uchar(*(p + 1))); ++ if (s != NULL) { ++ p += 2; goto init; /* return match(ms, s, p + 2) */ ++ } ++ break; ++ } ++ default: goto dflt; ++ } ++ break; ++ } ++ default: dflt: { /* pattern class plus optional suffix */ ++ const char *ep = classend(ms, p); /* points to optional suffix */ ++ /* does not match at least once? */ ++ if (!singlematch(ms, s, p, ep)) { ++ if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ ++ p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ ++ } ++ else /* '+' or no suffix */ ++ s = NULL; /* fail */ ++ } ++ else { /* matched once */ ++ switch (*ep) { /* handle optional suffix */ ++ case '?': { /* optional */ ++ const char *res; ++ if ((res = match(ms, s + 1, ep + 1)) != NULL) ++ s = res; ++ else { ++ p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ ++ } ++ break; ++ } ++ case '+': /* 1 or more repetitions */ ++ s++; /* 1 match already done */ ++ /* FALLTHROUGH */ ++ case '*': /* 0 or more repetitions */ ++ s = max_expand(ms, s, p, ep); ++ break; ++ case '-': /* 0 or more repetitions (minimum) */ ++ s = min_expand(ms, s, p, ep); ++ break; ++ default: /* no suffix */ ++ s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ ++ } ++ } ++ break; ++ } ++ } ++ } ++ ms->matchdepth++; ++ return s; ++} ++ ++ ++ ++static const char *lmemfind (const char *s1, size_t l1, ++ const char *s2, size_t l2) { ++ if (l2 == 0) return s1; /* empty strings are everywhere */ ++ else if (l2 > l1) return NULL; /* avoids a negative 'l1' */ ++ else { ++ const char *init; /* to search for a '*s2' inside 's1' */ ++ l2--; /* 1st char will be checked by 'memchr' */ ++ l1 = l1-l2; /* 's2' cannot be found after that */ ++ while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { ++ init++; /* 1st char is already checked */ ++ if (memcmp(init, s2+1, l2) == 0) ++ return init-1; ++ else { /* correct 'l1' and 's1' to try again */ ++ l1 -= init-s1; ++ s1 = init; ++ } ++ } ++ return NULL; /* not found */ ++ } ++} ++ ++ ++static void push_onecapture (MatchState *ms, int i, const char *s, ++ const char *e) { ++ if (i >= ms->level) { ++ if (i == 0) /* ms->level == 0, too */ ++ lua_pushlstring(ms->L, s, e - s); /* add whole match */ ++ else ++ luaL_error(ms->L, "invalid capture index %%%d", i + 1); ++ } ++ else { ++ ptrdiff_t l = ms->capture[i].len; ++ if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); ++ if (l == CAP_POSITION) ++ lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); ++ else ++ lua_pushlstring(ms->L, ms->capture[i].init, l); ++ } ++} ++ ++ ++static int push_captures (MatchState *ms, const char *s, const char *e) { ++ int i; ++ int nlevels = (ms->level == 0 && s) ? 1 : ms->level; ++ luaL_checkstack(ms->L, nlevels, "too many captures"); ++ for (i = 0; i < nlevels; i++) ++ push_onecapture(ms, i, s, e); ++ return nlevels; /* number of strings pushed */ ++} ++ ++ ++/* check whether pattern has no special characters */ ++static int nospecials (const char *p, size_t l) { ++ size_t upto = 0; ++ do { ++ if (strpbrk(p + upto, SPECIALS)) ++ return 0; /* pattern has a special character */ ++ upto += strlen(p + upto) + 1; /* may have more after \0 */ ++ } while (upto <= l); ++ return 1; /* no special chars found */ ++} ++ ++ ++static void prepstate (MatchState *ms, lua_State *L, ++ const char *s, size_t ls, const char *p, size_t lp) { ++ ms->L = L; ++ ms->matchdepth = MAXCCALLS; ++ ms->src_init = s; ++ ms->src_end = s + ls; ++ ms->p_end = p + lp; ++} ++ ++ ++static void reprepstate (MatchState *ms) { ++ ms->level = 0; ++ lua_assert(ms->matchdepth == MAXCCALLS); ++} ++ ++ ++static int str_find_aux (lua_State *L, int find) { ++ size_t ls, lp; ++ const char *s = luaL_checklstring(L, 1, &ls); ++ const char *p = luaL_checklstring(L, 2, &lp); ++ lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls); ++ if (init < 1) init = 1; ++ else if (init > (lua_Integer)ls + 1) { /* start after string's end? */ ++ lua_pushnil(L); /* cannot find anything */ ++ return 1; ++ } ++ /* explicit request or no special characters? */ ++ if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { ++ /* do a plain search */ ++ const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp); ++ if (s2) { ++ lua_pushinteger(L, (s2 - s) + 1); ++ lua_pushinteger(L, (s2 - s) + lp); ++ return 2; ++ } ++ } ++ else { ++ MatchState ms; ++ const char *s1 = s + init - 1; ++ int anchor = (*p == '^'); ++ if (anchor) { ++ p++; lp--; /* skip anchor character */ ++ } ++ prepstate(&ms, L, s, ls, p, lp); ++ do { ++ const char *res; ++ reprepstate(&ms); ++ if ((res=match(&ms, s1, p)) != NULL) { ++ if (find) { ++ lua_pushinteger(L, (s1 - s) + 1); /* start */ ++ lua_pushinteger(L, res - s); /* end */ ++ return push_captures(&ms, NULL, 0) + 2; ++ } ++ else ++ return push_captures(&ms, s1, res); ++ } ++ } while (s1++ < ms.src_end && !anchor); ++ } ++ lua_pushnil(L); /* not found */ ++ return 1; ++} ++ ++ ++static int str_find (lua_State *L) { ++ return str_find_aux(L, 1); ++} ++ ++ ++static int str_match (lua_State *L) { ++ return str_find_aux(L, 0); ++} ++ ++ ++/* state for 'gmatch' */ ++typedef struct GMatchState { ++ const char *src; /* current position */ ++ const char *p; /* pattern */ ++ const char *lastmatch; /* end of last match */ ++ MatchState ms; /* match state */ ++} GMatchState; ++ ++ ++static int gmatch_aux (lua_State *L) { ++ GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); ++ const char *src; ++ gm->ms.L = L; ++ for (src = gm->src; src <= gm->ms.src_end; src++) { ++ const char *e; ++ reprepstate(&gm->ms); ++ if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) { ++ gm->src = gm->lastmatch = e; ++ return push_captures(&gm->ms, src, e); ++ } ++ } ++ return 0; /* not found */ ++} ++ ++ ++static int gmatch (lua_State *L) { ++ size_t ls, lp; ++ const char *s = luaL_checklstring(L, 1, &ls); ++ const char *p = luaL_checklstring(L, 2, &lp); ++ GMatchState *gm; ++ lua_settop(L, 2); /* keep them on closure to avoid being collected */ ++ gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState)); ++ prepstate(&gm->ms, L, s, ls, p, lp); ++ gm->src = s; gm->p = p; gm->lastmatch = NULL; ++ lua_pushcclosure(L, gmatch_aux, 3); ++ return 1; ++} ++ ++ ++static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, ++ const char *e) { ++ size_t l, i; ++ lua_State *L = ms->L; ++ const char *news = lua_tolstring(L, 3, &l); ++ for (i = 0; i < l; i++) { ++ if (news[i] != L_ESC) ++ luaL_addchar(b, news[i]); ++ else { ++ i++; /* skip ESC */ ++ if (!isdigit(uchar(news[i]))) { ++ if (news[i] != L_ESC) ++ luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); ++ luaL_addchar(b, news[i]); ++ } ++ else if (news[i] == '0') ++ luaL_addlstring(b, s, e - s); ++ else { ++ push_onecapture(ms, news[i] - '1', s, e); ++ luaL_tolstring(L, -1, NULL); /* if number, convert it to string */ ++ lua_remove(L, -2); /* remove original value */ ++ luaL_addvalue(b); /* add capture to accumulated result */ ++ } ++ } ++ } ++} ++ ++ ++static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, ++ const char *e, int tr) { ++ lua_State *L = ms->L; ++ switch (tr) { ++ case LUA_TFUNCTION: { ++ int n; ++ lua_pushvalue(L, 3); ++ n = push_captures(ms, s, e); ++ lua_call(L, n, 1); ++ break; ++ } ++ case LUA_TTABLE: { ++ push_onecapture(ms, 0, s, e); ++ lua_gettable(L, 3); ++ break; ++ } ++ default: { /* LUA_TNUMBER or LUA_TSTRING */ ++ add_s(ms, b, s, e); ++ return; ++ } ++ } ++ if (!lua_toboolean(L, -1)) { /* nil or false? */ ++ lua_pop(L, 1); ++ lua_pushlstring(L, s, e - s); /* keep original text */ ++ } ++ else if (!lua_isstring(L, -1)) ++ luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); ++ luaL_addvalue(b); /* add result to accumulator */ ++} ++ ++ ++static int str_gsub (lua_State *L) { ++ size_t srcl, lp; ++ const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ ++ const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ ++ const char *lastmatch = NULL; /* end of last match */ ++ int tr = lua_type(L, 3); /* replacement type */ ++ lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ ++ int anchor = (*p == '^'); ++ lua_Integer n = 0; /* replacement count */ ++ MatchState ms; ++ luaL_Buffer b; ++ luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || ++ tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, ++ "string/function/table expected"); ++ luaL_buffinit(L, &b); ++ if (anchor) { ++ p++; lp--; /* skip anchor character */ ++ } ++ prepstate(&ms, L, src, srcl, p, lp); ++ while (n < max_s) { ++ const char *e; ++ reprepstate(&ms); /* (re)prepare state for new match */ ++ if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ ++ n++; ++ add_value(&ms, &b, src, e, tr); /* add replacement to buffer */ ++ src = lastmatch = e; ++ } ++ else if (src < ms.src_end) /* otherwise, skip one character */ ++ luaL_addchar(&b, *src++); ++ else break; /* end of subject */ ++ if (anchor) break; ++ } ++ luaL_addlstring(&b, src, ms.src_end-src); ++ luaL_pushresult(&b); ++ lua_pushinteger(L, n); /* number of substitutions */ ++ return 2; ++} ++ ++/* }====================================================== */ ++ ++ ++ ++/* ++** {====================================================== ++** STRING FORMAT ++** ======================================================= ++*/ ++ ++#if !defined(lua_number2strx) /* { */ ++ ++/* ++** Hexadecimal floating-point formatter ++*/ ++ ++#include ++ ++#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char)) ++ ++ ++/* ++** Number of bits that goes into the first digit. It can be any value ++** between 1 and 4; the following definition tries to align the number ++** to nibble boundaries by making what is left after that first digit a ++** multiple of 4. ++*/ ++#define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1) ++ ++ ++/* ++** Add integer part of 'x' to buffer and return new 'x' ++*/ ++static lua_Number adddigit (char *buff, int n, lua_Number x) { ++ lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */ ++ int d = (int)dd; ++ buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */ ++ return x - dd; /* return what is left */ ++} ++ ++ ++static int num2straux (char *buff, int sz, lua_Number x) { ++ /* if 'inf' or 'NaN', format it like '%g' */ ++ if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL) ++ return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x); ++ else if (x == 0) { /* can be -0... */ ++ /* create "0" or "-0" followed by exponent */ ++ return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x); ++ } ++ else { ++ int e; ++ lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */ ++ int n = 0; /* character count */ ++ if (m < 0) { /* is number negative? */ ++ buff[n++] = '-'; /* add signal */ ++ m = -m; /* make it positive */ ++ } ++ buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */ ++ m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */ ++ e -= L_NBFD; /* this digit goes before the radix point */ ++ if (m > 0) { /* more digits? */ ++ buff[n++] = lua_getlocaledecpoint(); /* add radix point */ ++ do { /* add as many digits as needed */ ++ m = adddigit(buff, n++, m * 16); ++ } while (m > 0); ++ } ++ n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */ ++ lua_assert(n < sz); ++ return n; ++ } ++} ++ ++ ++static int lua_number2strx (lua_State *L, char *buff, int sz, ++ const char *fmt, lua_Number x) { ++ int n = num2straux(buff, sz, x); ++ if (fmt[SIZELENMOD] == 'A') { ++ int i; ++ for (i = 0; i < n; i++) ++ buff[i] = toupper(uchar(buff[i])); ++ } ++ else if (fmt[SIZELENMOD] != 'a') ++ luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); ++ return n; ++} ++ ++#endif /* } */ ++ ++ ++/* ++** Maximum size of each formatted item. This maximum size is produced ++** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', ++** and '\0') + number of decimal digits to represent maxfloat (which ++** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra ++** expenses", such as locale-dependent stuff) ++*/ ++#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP)) ++ ++ ++/* valid flags in a format specification */ ++#define FLAGS "-+ #0" ++ ++/* ++** maximum size of each format specification (such as "%-099.99d") ++*/ ++#define MAX_FORMAT 32 ++ ++ ++static void addquoted (luaL_Buffer *b, const char *s, size_t len) { ++ luaL_addchar(b, '"'); ++ while (len--) { ++ if (*s == '"' || *s == '\\' || *s == '\n') { ++ luaL_addchar(b, '\\'); ++ luaL_addchar(b, *s); ++ } ++ else if (iscntrl(uchar(*s))) { ++ char buff[10]; ++ if (!isdigit(uchar(*(s+1)))) ++ l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s)); ++ else ++ l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s)); ++ luaL_addstring(b, buff); ++ } ++ else ++ luaL_addchar(b, *s); ++ s++; ++ } ++ luaL_addchar(b, '"'); ++} ++ ++ ++/* ++** Ensures the 'buff' string uses a dot as the radix character. ++*/ ++static void checkdp (char *buff, int nb) { ++ if (memchr(buff, '.', nb) == NULL) { /* no dot? */ ++ char point = lua_getlocaledecpoint(); /* try locale point */ ++ char *ppoint = (char *)memchr(buff, point, nb); ++ if (ppoint) *ppoint = '.'; /* change it to a dot */ ++ } ++} ++ ++ ++static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { ++ switch (lua_type(L, arg)) { ++ case LUA_TSTRING: { ++ size_t len; ++ const char *s = lua_tolstring(L, arg, &len); ++ addquoted(b, s, len); ++ break; ++ } ++ case LUA_TNUMBER: { ++ char *buff = luaL_prepbuffsize(b, MAX_ITEM); ++ int nb; ++ if (!lua_isinteger(L, arg)) { /* float? */ ++ lua_Number n = lua_tonumber(L, arg); /* write as hexa ('%a') */ ++ nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n); ++ checkdp(buff, nb); /* ensure it uses a dot */ ++ } ++ else { /* integers */ ++ lua_Integer n = lua_tointeger(L, arg); ++ const char *format = (n == LUA_MININTEGER) /* corner case? */ ++ ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */ ++ : LUA_INTEGER_FMT; /* else use default format */ ++ nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n); ++ } ++ luaL_addsize(b, nb); ++ break; ++ } ++ case LUA_TNIL: case LUA_TBOOLEAN: { ++ luaL_tolstring(L, arg, NULL); ++ luaL_addvalue(b); ++ break; ++ } ++ default: { ++ luaL_argerror(L, arg, "value has no literal form"); ++ } ++ } ++} ++ ++ ++static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { ++ const char *p = strfrmt; ++ while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ ++ if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) ++ luaL_error(L, "invalid format (repeated flags)"); ++ if (isdigit(uchar(*p))) p++; /* skip width */ ++ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ ++ if (*p == '.') { ++ p++; ++ if (isdigit(uchar(*p))) p++; /* skip precision */ ++ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ ++ } ++ if (isdigit(uchar(*p))) ++ luaL_error(L, "invalid format (width or precision too long)"); ++ *(form++) = '%'; ++ memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char)); ++ form += (p - strfrmt) + 1; ++ *form = '\0'; ++ return p; ++} ++ ++ ++/* ++** add length modifier into formats ++*/ ++static void addlenmod (char *form, const char *lenmod) { ++ size_t l = strlen(form); ++ size_t lm = strlen(lenmod); ++ char spec = form[l - 1]; ++ strcpy(form + l - 1, lenmod); ++ form[l + lm - 1] = spec; ++ form[l + lm] = '\0'; ++} ++ ++ ++static int str_format (lua_State *L) { ++ int top = lua_gettop(L); ++ int arg = 1; ++ size_t sfl; ++ const char *strfrmt = luaL_checklstring(L, arg, &sfl); ++ const char *strfrmt_end = strfrmt+sfl; ++ luaL_Buffer b; ++ luaL_buffinit(L, &b); ++ while (strfrmt < strfrmt_end) { ++ if (*strfrmt != L_ESC) ++ luaL_addchar(&b, *strfrmt++); ++ else if (*++strfrmt == L_ESC) ++ luaL_addchar(&b, *strfrmt++); /* %% */ ++ else { /* format item */ ++ char form[MAX_FORMAT]; /* to store the format ('%...') */ ++ char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ ++ int nb = 0; /* number of bytes in added item */ ++ if (++arg > top) ++ luaL_argerror(L, arg, "no value"); ++ strfrmt = scanformat(L, strfrmt, form); ++ switch (*strfrmt++) { ++ case 'c': { ++ nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg)); ++ break; ++ } ++ case 'd': case 'i': ++ case 'o': case 'u': case 'x': case 'X': { ++ lua_Integer n = luaL_checkinteger(L, arg); ++ addlenmod(form, LUA_INTEGER_FRMLEN); ++ nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n); ++ break; ++ } ++ case 'a': case 'A': ++ addlenmod(form, LUA_NUMBER_FRMLEN); ++ nb = lua_number2strx(L, buff, MAX_ITEM, form, ++ luaL_checknumber(L, arg)); ++ break; ++ case 'e': case 'E': case 'f': ++ case 'g': case 'G': { ++ lua_Number n = luaL_checknumber(L, arg); ++ addlenmod(form, LUA_NUMBER_FRMLEN); ++ nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n); ++ break; ++ } ++ case 'q': { ++ addliteral(L, &b, arg); ++ break; ++ } ++ case 's': { ++ size_t l; ++ const char *s = luaL_tolstring(L, arg, &l); ++ if (form[2] == '\0') /* no modifiers? */ ++ luaL_addvalue(&b); /* keep entire string */ ++ else { ++ luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); ++ if (!strchr(form, '.') && l >= 100) { ++ /* no precision and string is too long to be formatted */ ++ luaL_addvalue(&b); /* keep entire string */ ++ } ++ else { /* format the string into 'buff' */ ++ nb = l_sprintf(buff, MAX_ITEM, form, s); ++ lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ ++ } ++ } ++ break; ++ } ++ default: { /* also treat cases 'pnLlh' */ ++ return luaL_error(L, "invalid option '%%%c' to 'format'", ++ *(strfrmt - 1)); ++ } ++ } ++ lua_assert(nb < MAX_ITEM); ++ luaL_addsize(&b, nb); ++ } ++ } ++ luaL_pushresult(&b); ++ return 1; ++} ++ ++/* }====================================================== */ ++ ++ ++/* ++** {====================================================== ++** PACK/UNPACK ++** ======================================================= ++*/ ++ ++ ++/* value used for padding */ ++#if !defined(LUAL_PACKPADBYTE) ++#define LUAL_PACKPADBYTE 0x00 ++#endif ++ ++/* maximum size for the binary representation of an integer */ ++#define MAXINTSIZE 16 ++ ++/* number of bits in a character */ ++#define NB CHAR_BIT ++ ++/* mask for one character (NB 1's) */ ++#define MC ((1 << NB) - 1) ++ ++/* size of a lua_Integer */ ++#define SZINT ((int)sizeof(lua_Integer)) ++ ++ ++/* dummy union to get native endianness */ ++static const union { ++ int dummy; ++ char little; /* true iff machine is little endian */ ++} nativeendian = {1}; ++ ++ ++/* dummy structure to get native alignment requirements */ ++struct cD { ++ char c; ++ union { double d; void *p; lua_Integer i; lua_Number n; } u; ++}; ++ ++#define MAXALIGN (offsetof(struct cD, u)) ++ ++ ++/* ++** Union for serializing floats ++*/ ++typedef union Ftypes { ++ float f; ++ double d; ++ lua_Number n; ++ char buff[5 * sizeof(lua_Number)]; /* enough for any float type */ ++} Ftypes; ++ ++ ++/* ++** information to pack/unpack stuff ++*/ ++typedef struct Header { ++ lua_State *L; ++ int islittle; ++ int maxalign; ++} Header; ++ ++ ++/* ++** options for pack/unpack ++*/ ++typedef enum KOption { ++ Kint, /* signed integers */ ++ Kuint, /* unsigned integers */ ++ Kfloat, /* floating-point numbers */ ++ Kchar, /* fixed-length strings */ ++ Kstring, /* strings with prefixed length */ ++ Kzstr, /* zero-terminated strings */ ++ Kpadding, /* padding */ ++ Kpaddalign, /* padding for alignment */ ++ Knop /* no-op (configuration or spaces) */ ++} KOption; ++ ++ ++/* ++** Read an integer numeral from string 'fmt' or return 'df' if ++** there is no numeral ++*/ ++static int digit (int c) { return '0' <= c && c <= '9'; } ++ ++static int getnum (const char **fmt, int df) { ++ if (!digit(**fmt)) /* no number? */ ++ return df; /* return default value */ ++ else { ++ int a = 0; ++ do { ++ a = a*10 + (*((*fmt)++) - '0'); ++ } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10); ++ return a; ++ } ++} ++ ++ ++/* ++** Read an integer numeral and raises an error if it is larger ++** than the maximum size for integers. ++*/ ++static int getnumlimit (Header *h, const char **fmt, int df) { ++ int sz = getnum(fmt, df); ++ if (sz > MAXINTSIZE || sz <= 0) ++ luaL_error(h->L, "integral size (%d) out of limits [1,%d]", ++ sz, MAXINTSIZE); ++ return sz; ++} ++ ++ ++/* ++** Initialize Header ++*/ ++static void initheader (lua_State *L, Header *h) { ++ h->L = L; ++ h->islittle = nativeendian.little; ++ h->maxalign = 1; ++} ++ ++ ++/* ++** Read and classify next option. 'size' is filled with option's size. ++*/ ++static KOption getoption (Header *h, const char **fmt, int *size) { ++ int opt = *((*fmt)++); ++ *size = 0; /* default */ ++ switch (opt) { ++ case 'b': *size = sizeof(char); return Kint; ++ case 'B': *size = sizeof(char); return Kuint; ++ case 'h': *size = sizeof(short); return Kint; ++ case 'H': *size = sizeof(short); return Kuint; ++ case 'l': *size = sizeof(long); return Kint; ++ case 'L': *size = sizeof(long); return Kuint; ++ case 'j': *size = sizeof(lua_Integer); return Kint; ++ case 'J': *size = sizeof(lua_Integer); return Kuint; ++ case 'T': *size = sizeof(size_t); return Kuint; ++ case 'f': *size = sizeof(float); return Kfloat; ++ case 'd': *size = sizeof(double); return Kfloat; ++ case 'n': *size = sizeof(lua_Number); return Kfloat; ++ case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; ++ case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; ++ case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; ++ case 'c': ++ *size = getnum(fmt, -1); ++ if (*size == -1) ++ luaL_error(h->L, "missing size for format option 'c'"); ++ return Kchar; ++ case 'z': return Kzstr; ++ case 'x': *size = 1; return Kpadding; ++ case 'X': return Kpaddalign; ++ case ' ': break; ++ case '<': h->islittle = 1; break; ++ case '>': h->islittle = 0; break; ++ case '=': h->islittle = nativeendian.little; break; ++ case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break; ++ default: luaL_error(h->L, "invalid format option '%c'", opt); ++ } ++ return Knop; ++} ++ ++ ++/* ++** Read, classify, and fill other details about the next option. ++** 'psize' is filled with option's size, 'notoalign' with its ++** alignment requirements. ++** Local variable 'size' gets the size to be aligned. (Kpadal option ++** always gets its full alignment, other options are limited by ++** the maximum alignment ('maxalign'). Kchar option needs no alignment ++** despite its size. ++*/ ++static KOption getdetails (Header *h, size_t totalsize, ++ const char **fmt, int *psize, int *ntoalign) { ++ KOption opt = getoption(h, fmt, psize); ++ int align = *psize; /* usually, alignment follows size */ ++ if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ ++ if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) ++ luaL_argerror(h->L, 1, "invalid next option for option 'X'"); ++ } ++ if (align <= 1 || opt == Kchar) /* need no alignment? */ ++ *ntoalign = 0; ++ else { ++ if (align > h->maxalign) /* enforce maximum alignment */ ++ align = h->maxalign; ++ if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ ++ luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); ++ *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); ++ } ++ return opt; ++} ++ ++ ++/* ++** Pack integer 'n' with 'size' bytes and 'islittle' endianness. ++** The final 'if' handles the case when 'size' is larger than ++** the size of a Lua integer, correcting the extra sign-extension ++** bytes if necessary (by default they would be zeros). ++*/ ++static void packint (luaL_Buffer *b, lua_Unsigned n, ++ int islittle, int size, int neg) { ++ char *buff = luaL_prepbuffsize(b, size); ++ int i; ++ buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ ++ for (i = 1; i < size; i++) { ++ n >>= NB; ++ buff[islittle ? i : size - 1 - i] = (char)(n & MC); ++ } ++ if (neg && size > SZINT) { /* negative number need sign extension? */ ++ for (i = SZINT; i < size; i++) /* correct extra bytes */ ++ buff[islittle ? i : size - 1 - i] = (char)MC; ++ } ++ luaL_addsize(b, size); /* add result to buffer */ ++} ++ ++ ++/* ++** Copy 'size' bytes from 'src' to 'dest', correcting endianness if ++** given 'islittle' is different from native endianness. ++*/ ++static void copywithendian (volatile char *dest, volatile const char *src, ++ int size, int islittle) { ++ if (islittle == nativeendian.little) { ++ while (size-- != 0) ++ *(dest++) = *(src++); ++ } ++ else { ++ dest += size - 1; ++ while (size-- != 0) ++ *(dest--) = *(src++); ++ } ++} ++ ++ ++static int str_pack (lua_State *L) { ++ luaL_Buffer b; ++ Header h; ++ const char *fmt = luaL_checkstring(L, 1); /* format string */ ++ int arg = 1; /* current argument to pack */ ++ size_t totalsize = 0; /* accumulate total size of result */ ++ initheader(L, &h); ++ lua_pushnil(L); /* mark to separate arguments from string buffer */ ++ luaL_buffinit(L, &b); ++ while (*fmt != '\0') { ++ int size, ntoalign; ++ KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); ++ totalsize += ntoalign + size; ++ while (ntoalign-- > 0) ++ luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ ++ arg++; ++ switch (opt) { ++ case Kint: { /* signed integers */ ++ lua_Integer n = luaL_checkinteger(L, arg); ++ if (size < SZINT) { /* need overflow check? */ ++ lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); ++ luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); ++ } ++ packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); ++ break; ++ } ++ case Kuint: { /* unsigned integers */ ++ lua_Integer n = luaL_checkinteger(L, arg); ++ if (size < SZINT) /* need overflow check? */ ++ luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), ++ arg, "unsigned overflow"); ++ packint(&b, (lua_Unsigned)n, h.islittle, size, 0); ++ break; ++ } ++ case Kfloat: { /* floating-point options */ ++ volatile Ftypes u; ++ char *buff = luaL_prepbuffsize(&b, size); ++ lua_Number n = luaL_checknumber(L, arg); /* get argument */ ++ if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ ++ else if (size == sizeof(u.d)) u.d = (double)n; ++ else u.n = n; ++ /* move 'u' to final result, correcting endianness if needed */ ++ copywithendian(buff, u.buff, size, h.islittle); ++ luaL_addsize(&b, size); ++ break; ++ } ++ case Kchar: { /* fixed-size string */ ++ size_t len; ++ const char *s = luaL_checklstring(L, arg, &len); ++ luaL_argcheck(L, len <= (size_t)size, arg, ++ "string longer than given size"); ++ luaL_addlstring(&b, s, len); /* add string */ ++ while (len++ < (size_t)size) /* pad extra space */ ++ luaL_addchar(&b, LUAL_PACKPADBYTE); ++ break; ++ } ++ case Kstring: { /* strings with length count */ ++ size_t len; ++ const char *s = luaL_checklstring(L, arg, &len); ++ luaL_argcheck(L, size >= (int)sizeof(size_t) || ++ len < ((size_t)1 << (size * NB)), ++ arg, "string length does not fit in given size"); ++ packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ ++ luaL_addlstring(&b, s, len); ++ totalsize += len; ++ break; ++ } ++ case Kzstr: { /* zero-terminated string */ ++ size_t len; ++ const char *s = luaL_checklstring(L, arg, &len); ++ luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); ++ luaL_addlstring(&b, s, len); ++ luaL_addchar(&b, '\0'); /* add zero at the end */ ++ totalsize += len + 1; ++ break; ++ } ++ case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ ++ case Kpaddalign: case Knop: ++ arg--; /* undo increment */ ++ break; ++ } ++ } ++ luaL_pushresult(&b); ++ return 1; ++} ++ ++ ++static int str_packsize (lua_State *L) { ++ Header h; ++ const char *fmt = luaL_checkstring(L, 1); /* format string */ ++ size_t totalsize = 0; /* accumulate total size of result */ ++ initheader(L, &h); ++ while (*fmt != '\0') { ++ int size, ntoalign; ++ KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); ++ size += ntoalign; /* total space used by option */ ++ luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, ++ "format result too large"); ++ totalsize += size; ++ switch (opt) { ++ case Kstring: /* strings with length count */ ++ case Kzstr: /* zero-terminated string */ ++ luaL_argerror(L, 1, "variable-length format"); ++ /* call never return, but to avoid warnings: *//* FALLTHROUGH */ ++ default: break; ++ } ++ } ++ lua_pushinteger(L, (lua_Integer)totalsize); ++ return 1; ++} ++ ++ ++/* ++** Unpack an integer with 'size' bytes and 'islittle' endianness. ++** If size is smaller than the size of a Lua integer and integer ++** is signed, must do sign extension (propagating the sign to the ++** higher bits); if size is larger than the size of a Lua integer, ++** it must check the unread bytes to see whether they do not cause an ++** overflow. ++*/ ++static lua_Integer unpackint (lua_State *L, const char *str, ++ int islittle, int size, int issigned) { ++ lua_Unsigned res = 0; ++ int i; ++ int limit = (size <= SZINT) ? size : SZINT; ++ for (i = limit - 1; i >= 0; i--) { ++ res <<= NB; ++ res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; ++ } ++ if (size < SZINT) { /* real size smaller than lua_Integer? */ ++ if (issigned) { /* needs sign extension? */ ++ lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); ++ res = ((res ^ mask) - mask); /* do sign extension */ ++ } ++ } ++ else if (size > SZINT) { /* must check unread bytes */ ++ int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; ++ for (i = limit; i < size; i++) { ++ if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) ++ luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); ++ } ++ } ++ return (lua_Integer)res; ++} ++ ++ ++static int str_unpack (lua_State *L) { ++ Header h; ++ const char *fmt = luaL_checkstring(L, 1); ++ size_t ld; ++ const char *data = luaL_checklstring(L, 2, &ld); ++ size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; ++ int n = 0; /* number of results */ ++ luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); ++ initheader(L, &h); ++ while (*fmt != '\0') { ++ int size, ntoalign; ++ KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); ++ if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) ++ luaL_argerror(L, 2, "data string too short"); ++ pos += ntoalign; /* skip alignment */ ++ /* stack space for item + next position */ ++ luaL_checkstack(L, 2, "too many results"); ++ n++; ++ switch (opt) { ++ case Kint: ++ case Kuint: { ++ lua_Integer res = unpackint(L, data + pos, h.islittle, size, ++ (opt == Kint)); ++ lua_pushinteger(L, res); ++ break; ++ } ++ case Kfloat: { ++ volatile Ftypes u; ++ lua_Number num; ++ copywithendian(u.buff, data + pos, size, h.islittle); ++ if (size == sizeof(u.f)) num = (lua_Number)u.f; ++ else if (size == sizeof(u.d)) num = (lua_Number)u.d; ++ else num = u.n; ++ lua_pushnumber(L, num); ++ break; ++ } ++ case Kchar: { ++ lua_pushlstring(L, data + pos, size); ++ break; ++ } ++ case Kstring: { ++ size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); ++ luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); ++ lua_pushlstring(L, data + pos + size, len); ++ pos += len; /* skip string */ ++ break; ++ } ++ case Kzstr: { ++ size_t len = (int)strlen(data + pos); ++ lua_pushlstring(L, data + pos, len); ++ pos += len + 1; /* skip string plus final '\0' */ ++ break; ++ } ++ case Kpaddalign: case Kpadding: case Knop: ++ n--; /* undo increment */ ++ break; ++ } ++ pos += size; ++ } ++ lua_pushinteger(L, pos + 1); /* next position */ ++ return n + 1; ++} ++ ++/* }====================================================== */ ++ ++ ++static const luaL_Reg strlib[] = { ++ {"byte", str_byte}, ++ {"char", str_char}, ++ {"dump", str_dump}, ++ {"find", str_find}, ++ {"format", str_format}, ++ {"gmatch", gmatch}, ++ {"gsub", str_gsub}, ++ {"len", str_len}, ++ {"lower", str_lower}, ++ {"match", str_match}, ++ {"rep", str_rep}, ++ {"reverse", str_reverse}, ++ {"sub", str_sub}, ++ {"upper", str_upper}, ++ {"pack", str_pack}, ++ {"packsize", str_packsize}, ++ {"unpack", str_unpack}, ++ {NULL, NULL} ++}; ++ ++ ++static void createmetatable (lua_State *L) { ++ lua_createtable(L, 0, 1); /* table to be metatable for strings */ ++ lua_pushliteral(L, ""); /* dummy string */ ++ lua_pushvalue(L, -2); /* copy table */ ++ lua_setmetatable(L, -2); /* set table as metatable for strings */ ++ lua_pop(L, 1); /* pop dummy string */ ++ lua_pushvalue(L, -2); /* get string library */ ++ lua_setfield(L, -2, "__index"); /* metatable.__index = string */ ++ lua_pop(L, 1); /* pop metatable */ ++} ++ ++ ++/* ++** Open string library ++*/ ++LUAMOD_API int luaopen_string (lua_State *L) { ++ luaL_newlib(L, strlib); ++ createmetatable(L); ++ return 1; ++} ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/ltablib.c luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/ltablib.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/ltablib.c 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/ltablib.c 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,450 @@ ++/* ++** $Id: ltablib.c,v 1.93 2016/02/25 19:41:54 roberto Exp $ ++** Library for Table Manipulation ++** See Copyright Notice in lua.h ++*/ ++ ++#define ltablib_c ++#define LUA_LIB ++ ++#include "lprefix.h" ++ ++ ++#include ++#include ++#include ++ ++#include "lua.h" ++ ++#include "lauxlib.h" ++#include "lualib.h" ++ ++ ++/* ++** Operations that an object must define to mimic a table ++** (some functions only need some of them) ++*/ ++#define TAB_R 1 /* read */ ++#define TAB_W 2 /* write */ ++#define TAB_L 4 /* length */ ++#define TAB_RW (TAB_R | TAB_W) /* read/write */ ++ ++ ++#define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n)) ++ ++ ++static int checkfield (lua_State *L, const char *key, int n) { ++ lua_pushstring(L, key); ++ return (lua_rawget(L, -n) != LUA_TNIL); ++} ++ ++ ++/* ++** Check that 'arg' either is a table or can behave like one (that is, ++** has a metatable with the required metamethods) ++*/ ++static void checktab (lua_State *L, int arg, int what) { ++ if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */ ++ int n = 1; /* number of elements to pop */ ++ if (lua_getmetatable(L, arg) && /* must have metatable */ ++ (!(what & TAB_R) || checkfield(L, "__index", ++n)) && ++ (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && ++ (!(what & TAB_L) || checkfield(L, "__len", ++n))) { ++ lua_pop(L, n); /* pop metatable and tested metamethods */ ++ } ++ else ++ luaL_checktype(L, arg, LUA_TTABLE); /* force an error */ ++ } ++} ++ ++ ++#if defined(LUA_COMPAT_MAXN) ++static int maxn (lua_State *L) { ++ lua_Number max = 0; ++ luaL_checktype(L, 1, LUA_TTABLE); ++ lua_pushnil(L); /* first key */ ++ while (lua_next(L, 1)) { ++ lua_pop(L, 1); /* remove value */ ++ if (lua_type(L, -1) == LUA_TNUMBER) { ++ lua_Number v = lua_tonumber(L, -1); ++ if (v > max) max = v; ++ } ++ } ++ lua_pushnumber(L, max); ++ return 1; ++} ++#endif ++ ++ ++static int tinsert (lua_State *L) { ++ lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ ++ lua_Integer pos; /* where to insert new element */ ++ switch (lua_gettop(L)) { ++ case 2: { /* called with only 2 arguments */ ++ pos = e; /* insert new element at the end */ ++ break; ++ } ++ case 3: { ++ lua_Integer i; ++ pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ ++ luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); ++ for (i = e; i > pos; i--) { /* move up elements */ ++ lua_geti(L, 1, i - 1); ++ lua_seti(L, 1, i); /* t[i] = t[i - 1] */ ++ } ++ break; ++ } ++ default: { ++ return luaL_error(L, "wrong number of arguments to 'insert'"); ++ } ++ } ++ lua_seti(L, 1, pos); /* t[pos] = v */ ++ return 0; ++} ++ ++ ++static int tremove (lua_State *L) { ++ lua_Integer size = aux_getn(L, 1, TAB_RW); ++ lua_Integer pos = luaL_optinteger(L, 2, size); ++ if (pos != size) /* validate 'pos' if given */ ++ luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); ++ lua_geti(L, 1, pos); /* result = t[pos] */ ++ for ( ; pos < size; pos++) { ++ lua_geti(L, 1, pos + 1); ++ lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ ++ } ++ lua_pushnil(L); ++ lua_seti(L, 1, pos); /* t[pos] = nil */ ++ return 1; ++} ++ ++ ++/* ++** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever ++** possible, copy in increasing order, which is better for rehashing. ++** "possible" means destination after original range, or smaller ++** than origin, or copying to another table. ++*/ ++static int tmove (lua_State *L) { ++ lua_Integer f = luaL_checkinteger(L, 2); ++ lua_Integer e = luaL_checkinteger(L, 3); ++ lua_Integer t = luaL_checkinteger(L, 4); ++ int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ ++ checktab(L, 1, TAB_R); ++ checktab(L, tt, TAB_W); ++ if (e >= f) { /* otherwise, nothing to move */ ++ lua_Integer n, i; ++ luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, ++ "too many elements to move"); ++ n = e - f + 1; /* number of elements to move */ ++ luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, ++ "destination wrap around"); ++ if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { ++ for (i = 0; i < n; i++) { ++ lua_geti(L, 1, f + i); ++ lua_seti(L, tt, t + i); ++ } ++ } ++ else { ++ for (i = n - 1; i >= 0; i--) { ++ lua_geti(L, 1, f + i); ++ lua_seti(L, tt, t + i); ++ } ++ } ++ } ++ lua_pushvalue(L, tt); /* return destination table */ ++ return 1; ++} ++ ++ ++static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { ++ lua_geti(L, 1, i); ++ if (!lua_isstring(L, -1)) ++ luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", ++ luaL_typename(L, -1), i); ++ luaL_addvalue(b); ++} ++ ++ ++static int tconcat (lua_State *L) { ++ luaL_Buffer b; ++ lua_Integer last = aux_getn(L, 1, TAB_R); ++ size_t lsep; ++ const char *sep = luaL_optlstring(L, 2, "", &lsep); ++ lua_Integer i = luaL_optinteger(L, 3, 1); ++ last = luaL_optinteger(L, 4, last); ++ luaL_buffinit(L, &b); ++ for (; i < last; i++) { ++ addfield(L, &b, i); ++ luaL_addlstring(&b, sep, lsep); ++ } ++ if (i == last) /* add last value (if interval was not empty) */ ++ addfield(L, &b, i); ++ luaL_pushresult(&b); ++ return 1; ++} ++ ++ ++/* ++** {====================================================== ++** Pack/unpack ++** ======================================================= ++*/ ++ ++static int pack (lua_State *L) { ++ int i; ++ int n = lua_gettop(L); /* number of elements to pack */ ++ lua_createtable(L, n, 1); /* create result table */ ++ lua_insert(L, 1); /* put it at index 1 */ ++ for (i = n; i >= 1; i--) /* assign elements */ ++ lua_seti(L, 1, i); ++ lua_pushinteger(L, n); ++ lua_setfield(L, 1, "n"); /* t.n = number of elements */ ++ return 1; /* return table */ ++} ++ ++ ++static int unpack (lua_State *L) { ++ lua_Unsigned n; ++ lua_Integer i = luaL_optinteger(L, 2, 1); ++ lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); ++ if (i > e) return 0; /* empty range */ ++ n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ ++ if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) ++ return luaL_error(L, "too many results to unpack"); ++ for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */ ++ lua_geti(L, 1, i); ++ } ++ lua_geti(L, 1, e); /* push last element */ ++ return (int)n; ++} ++ ++/* }====================================================== */ ++ ++ ++ ++/* ++** {====================================================== ++** Quicksort ++** (based on 'Algorithms in MODULA-3', Robert Sedgewick; ++** Addison-Wesley, 1993.) ++** ======================================================= ++*/ ++ ++ ++/* type for array indices */ ++typedef unsigned int IdxT; ++ ++ ++/* ++** Produce a "random" 'unsigned int' to randomize pivot choice. This ++** macro is used only when 'sort' detects a big imbalance in the result ++** of a partition. (If you don't want/need this "randomness", ~0 is a ++** good choice.) ++*/ ++#if !defined(l_randomizePivot) /* { */ ++ ++#include ++ ++/* size of 'e' measured in number of 'unsigned int's */ ++#define sof(e) (sizeof(e) / sizeof(unsigned int)) ++ ++/* ++** Use 'time' and 'clock' as sources of "randomness". Because we don't ++** know the types 'clock_t' and 'time_t', we cannot cast them to ++** anything without risking overflows. A safe way to use their values ++** is to copy them to an array of a known type and use the array values. ++*/ ++static unsigned int l_randomizePivot (void) { ++ clock_t c = clock(); ++ time_t t = time(NULL); ++ unsigned int buff[sof(c) + sof(t)]; ++ unsigned int i, rnd = 0; ++ memcpy(buff, &c, sof(c) * sizeof(unsigned int)); ++ memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int)); ++ for (i = 0; i < sof(buff); i++) ++ rnd += buff[i]; ++ return rnd; ++} ++ ++#endif /* } */ ++ ++ ++/* arrays larger than 'RANLIMIT' may use randomized pivots */ ++#define RANLIMIT 100u ++ ++ ++static void set2 (lua_State *L, IdxT i, IdxT j) { ++ lua_seti(L, 1, i); ++ lua_seti(L, 1, j); ++} ++ ++ ++/* ++** Return true iff value at stack index 'a' is less than the value at ++** index 'b' (according to the order of the sort). ++*/ ++static int sort_comp (lua_State *L, int a, int b) { ++ if (lua_isnil(L, 2)) /* no function? */ ++ return lua_compare(L, a, b, LUA_OPLT); /* a < b */ ++ else { /* function */ ++ int res; ++ lua_pushvalue(L, 2); /* push function */ ++ lua_pushvalue(L, a-1); /* -1 to compensate function */ ++ lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ ++ lua_call(L, 2, 1); /* call function */ ++ res = lua_toboolean(L, -1); /* get result */ ++ lua_pop(L, 1); /* pop result */ ++ return res; ++ } ++} ++ ++ ++/* ++** Does the partition: Pivot P is at the top of the stack. ++** precondition: a[lo] <= P == a[up-1] <= a[up], ++** so it only needs to do the partition from lo + 1 to up - 2. ++** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] ++** returns 'i'. ++*/ ++static IdxT partition (lua_State *L, IdxT lo, IdxT up) { ++ IdxT i = lo; /* will be incremented before first use */ ++ IdxT j = up - 1; /* will be decremented before first use */ ++ /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ ++ for (;;) { ++ /* next loop: repeat ++i while a[i] < P */ ++ while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { ++ if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ ++ luaL_error(L, "invalid order function for sorting"); ++ lua_pop(L, 1); /* remove a[i] */ ++ } ++ /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ ++ /* next loop: repeat --j while P < a[j] */ ++ while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { ++ if (j < i) /* j < i but a[j] > P ?? */ ++ luaL_error(L, "invalid order function for sorting"); ++ lua_pop(L, 1); /* remove a[j] */ ++ } ++ /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ ++ if (j < i) { /* no elements out of place? */ ++ /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ ++ lua_pop(L, 1); /* pop a[j] */ ++ /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ ++ set2(L, up - 1, i); ++ return i; ++ } ++ /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ ++ set2(L, i, j); ++ } ++} ++ ++ ++/* ++** Choose an element in the middle (2nd-3th quarters) of [lo,up] ++** "randomized" by 'rnd' ++*/ ++static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { ++ IdxT r4 = (up - lo) / 4; /* range/4 */ ++ IdxT p = rnd % (r4 * 2) + (lo + r4); ++ lua_assert(lo + r4 <= p && p <= up - r4); ++ return p; ++} ++ ++ ++/* ++** QuickSort algorithm (recursive function) ++*/ ++static void auxsort (lua_State *L, IdxT lo, IdxT up, ++ unsigned int rnd) { ++ while (lo < up) { /* loop for tail recursion */ ++ IdxT p; /* Pivot index */ ++ IdxT n; /* to be used later */ ++ /* sort elements 'lo', 'p', and 'up' */ ++ lua_geti(L, 1, lo); ++ lua_geti(L, 1, up); ++ if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ ++ set2(L, lo, up); /* swap a[lo] - a[up] */ ++ else ++ lua_pop(L, 2); /* remove both values */ ++ if (up - lo == 1) /* only 2 elements? */ ++ return; /* already sorted */ ++ if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */ ++ p = (lo + up)/2; /* middle element is a good pivot */ ++ else /* for larger intervals, it is worth a random pivot */ ++ p = choosePivot(lo, up, rnd); ++ lua_geti(L, 1, p); ++ lua_geti(L, 1, lo); ++ if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */ ++ set2(L, p, lo); /* swap a[p] - a[lo] */ ++ else { ++ lua_pop(L, 1); /* remove a[lo] */ ++ lua_geti(L, 1, up); ++ if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */ ++ set2(L, p, up); /* swap a[up] - a[p] */ ++ else ++ lua_pop(L, 2); ++ } ++ if (up - lo == 2) /* only 3 elements? */ ++ return; /* already sorted */ ++ lua_geti(L, 1, p); /* get middle element (Pivot) */ ++ lua_pushvalue(L, -1); /* push Pivot */ ++ lua_geti(L, 1, up - 1); /* push a[up - 1] */ ++ set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ ++ p = partition(L, lo, up); ++ /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ ++ if (p - lo < up - p) { /* lower interval is smaller? */ ++ auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */ ++ n = p - lo; /* size of smaller interval */ ++ lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */ ++ } ++ else { ++ auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */ ++ n = up - p; /* size of smaller interval */ ++ up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */ ++ } ++ if ((up - lo) / 128 > n) /* partition too imbalanced? */ ++ rnd = l_randomizePivot(); /* try a new randomization */ ++ } /* tail call auxsort(L, lo, up, rnd) */ ++} ++ ++ ++static int sort (lua_State *L) { ++ lua_Integer n = aux_getn(L, 1, TAB_RW); ++ if (n > 1) { /* non-trivial interval? */ ++ luaL_argcheck(L, n < INT_MAX, 1, "array too big"); ++ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ ++ luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ ++ lua_settop(L, 2); /* make sure there are two arguments */ ++ auxsort(L, 1, (IdxT)n, 0); ++ } ++ return 0; ++} ++ ++/* }====================================================== */ ++ ++ ++static const luaL_Reg tab_funcs[] = { ++ {"concat", tconcat}, ++#if defined(LUA_COMPAT_MAXN) ++ {"maxn", maxn}, ++#endif ++ {"insert", tinsert}, ++ {"pack", pack}, ++ {"unpack", unpack}, ++ {"remove", tremove}, ++ {"move", tmove}, ++ {"sort", sort}, ++ {NULL, NULL} ++}; ++ ++ ++LUAMOD_API int luaopen_table (lua_State *L) { ++ luaL_newlib(L, tab_funcs); ++#if defined(LUA_COMPAT_UNPACK) ++ /* _G.unpack = table.unpack */ ++ lua_getfield(L, -1, "unpack"); ++ lua_setglobal(L, "unpack"); ++#endif ++ return 1; ++} ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/lutf8lib.c luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/lutf8lib.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/lutf8lib.c 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/lutf8lib.c 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,256 @@ ++/* ++** $Id: lutf8lib.c,v 1.16 2016/12/22 13:08:50 roberto Exp $ ++** Standard library for UTF-8 manipulation ++** See Copyright Notice in lua.h ++*/ ++ ++#define lutf8lib_c ++#define LUA_LIB ++ ++#include "lprefix.h" ++ ++ ++#include ++#include ++#include ++#include ++ ++#include "lua.h" ++ ++#include "lauxlib.h" ++#include "lualib.h" ++ ++#define MAXUNICODE 0x10FFFF ++ ++#define iscont(p) ((*(p) & 0xC0) == 0x80) ++ ++ ++/* from strlib */ ++/* translate a relative string position: negative means back from end */ ++static lua_Integer u_posrelat (lua_Integer pos, size_t len) { ++ if (pos >= 0) return pos; ++ else if (0u - (size_t)pos > len) return 0; ++ else return (lua_Integer)len + pos + 1; ++} ++ ++ ++/* ++** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. ++*/ ++static const char *utf8_decode (const char *o, int *val) { ++ static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; ++ const unsigned char *s = (const unsigned char *)o; ++ unsigned int c = s[0]; ++ unsigned int res = 0; /* final result */ ++ if (c < 0x80) /* ascii? */ ++ res = c; ++ else { ++ int count = 0; /* to count number of continuation bytes */ ++ while (c & 0x40) { /* still have continuation bytes? */ ++ int cc = s[++count]; /* read next byte */ ++ if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ ++ return NULL; /* invalid byte sequence */ ++ res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ ++ c <<= 1; /* to test next bit */ ++ } ++ res |= ((c & 0x7F) << (count * 5)); /* add first byte */ ++ if (count > 3 || res > MAXUNICODE || res <= limits[count]) ++ return NULL; /* invalid byte sequence */ ++ s += count; /* skip continuation bytes read */ ++ } ++ if (val) *val = res; ++ return (const char *)s + 1; /* +1 to include first byte */ ++} ++ ++ ++/* ++** utf8len(s [, i [, j]]) --> number of characters that start in the ++** range [i,j], or nil + current position if 's' is not well formed in ++** that interval ++*/ ++static int utflen (lua_State *L) { ++ int n = 0; ++ size_t len; ++ const char *s = luaL_checklstring(L, 1, &len); ++ lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); ++ lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); ++ luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, ++ "initial position out of string"); ++ luaL_argcheck(L, --posj < (lua_Integer)len, 3, ++ "final position out of string"); ++ while (posi <= posj) { ++ const char *s1 = utf8_decode(s + posi, NULL); ++ if (s1 == NULL) { /* conversion error? */ ++ lua_pushnil(L); /* return nil ... */ ++ lua_pushinteger(L, posi + 1); /* ... and current position */ ++ return 2; ++ } ++ posi = s1 - s; ++ n++; ++ } ++ lua_pushinteger(L, n); ++ return 1; ++} ++ ++ ++/* ++** codepoint(s, [i, [j]]) -> returns codepoints for all characters ++** that start in the range [i,j] ++*/ ++static int codepoint (lua_State *L) { ++ size_t len; ++ const char *s = luaL_checklstring(L, 1, &len); ++ lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); ++ lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); ++ int n; ++ const char *se; ++ luaL_argcheck(L, posi >= 1, 2, "out of range"); ++ luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); ++ if (posi > pose) return 0; /* empty interval; return no values */ ++ if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ ++ return luaL_error(L, "string slice too long"); ++ n = (int)(pose - posi) + 1; ++ luaL_checkstack(L, n, "string slice too long"); ++ n = 0; ++ se = s + pose; ++ for (s += posi - 1; s < se;) { ++ int code; ++ s = utf8_decode(s, &code); ++ if (s == NULL) ++ return luaL_error(L, "invalid UTF-8 code"); ++ lua_pushinteger(L, code); ++ n++; ++ } ++ return n; ++} ++ ++ ++static void pushutfchar (lua_State *L, int arg) { ++ lua_Integer code = luaL_checkinteger(L, arg); ++ luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); ++ lua_pushfstring(L, "%U", (long)code); ++} ++ ++ ++/* ++** utfchar(n1, n2, ...) -> char(n1)..char(n2)... ++*/ ++static int utfchar (lua_State *L) { ++ int n = lua_gettop(L); /* number of arguments */ ++ if (n == 1) /* optimize common case of single char */ ++ pushutfchar(L, 1); ++ else { ++ int i; ++ luaL_Buffer b; ++ luaL_buffinit(L, &b); ++ for (i = 1; i <= n; i++) { ++ pushutfchar(L, i); ++ luaL_addvalue(&b); ++ } ++ luaL_pushresult(&b); ++ } ++ return 1; ++} ++ ++ ++/* ++** offset(s, n, [i]) -> index where n-th character counting from ++** position 'i' starts; 0 means character at 'i'. ++*/ ++static int byteoffset (lua_State *L) { ++ size_t len; ++ const char *s = luaL_checklstring(L, 1, &len); ++ lua_Integer n = luaL_checkinteger(L, 2); ++ lua_Integer posi = (n >= 0) ? 1 : len + 1; ++ posi = u_posrelat(luaL_optinteger(L, 3, posi), len); ++ luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, ++ "position out of range"); ++ if (n == 0) { ++ /* find beginning of current byte sequence */ ++ while (posi > 0 && iscont(s + posi)) posi--; ++ } ++ else { ++ if (iscont(s + posi)) ++ luaL_error(L, "initial position is a continuation byte"); ++ if (n < 0) { ++ while (n < 0 && posi > 0) { /* move back */ ++ do { /* find beginning of previous character */ ++ posi--; ++ } while (posi > 0 && iscont(s + posi)); ++ n++; ++ } ++ } ++ else { ++ n--; /* do not move for 1st character */ ++ while (n > 0 && posi < (lua_Integer)len) { ++ do { /* find beginning of next character */ ++ posi++; ++ } while (iscont(s + posi)); /* (cannot pass final '\0') */ ++ n--; ++ } ++ } ++ } ++ if (n == 0) /* did it find given character? */ ++ lua_pushinteger(L, posi + 1); ++ else /* no such character */ ++ lua_pushnil(L); ++ return 1; ++} ++ ++ ++static int iter_aux (lua_State *L) { ++ size_t len; ++ const char *s = luaL_checklstring(L, 1, &len); ++ lua_Integer n = lua_tointeger(L, 2) - 1; ++ if (n < 0) /* first iteration? */ ++ n = 0; /* start from here */ ++ else if (n < (lua_Integer)len) { ++ n++; /* skip current byte */ ++ while (iscont(s + n)) n++; /* and its continuations */ ++ } ++ if (n >= (lua_Integer)len) ++ return 0; /* no more codepoints */ ++ else { ++ int code; ++ const char *next = utf8_decode(s + n, &code); ++ if (next == NULL || iscont(next)) ++ return luaL_error(L, "invalid UTF-8 code"); ++ lua_pushinteger(L, n + 1); ++ lua_pushinteger(L, code); ++ return 2; ++ } ++} ++ ++ ++static int iter_codes (lua_State *L) { ++ luaL_checkstring(L, 1); ++ lua_pushcfunction(L, iter_aux); ++ lua_pushvalue(L, 1); ++ lua_pushinteger(L, 0); ++ return 3; ++} ++ ++ ++/* pattern to match a single UTF-8 character */ ++#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" ++ ++ ++static const luaL_Reg funcs[] = { ++ {"offset", byteoffset}, ++ {"codepoint", codepoint}, ++ {"char", utfchar}, ++ {"len", utflen}, ++ {"codes", iter_codes}, ++ /* placeholders */ ++ {"charpattern", NULL}, ++ {NULL, NULL} ++}; ++ ++ ++LUAMOD_API int luaopen_utf8 (lua_State *L) { ++ luaL_newlib(L, funcs); ++ lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); ++ lua_setfield(L, -2, "charpattern"); ++ return 1; ++} ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/README.md luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/README.md +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/README.md 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/README.md 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,239 @@ ++[![Build Status](https://travis-ci.org/keplerproject/lua-compat-5.3.svg?branch=master)](https://travis-ci.org/keplerproject/lua-compat-5.3) ++ ++# lua-compat-5.3 ++ ++Lua-5.3-style APIs for Lua 5.2 and 5.1. ++ ++## What is it ++ ++This is a small module that aims to make it easier to write code ++in a Lua-5.3-style that is compatible with Lua 5.1, Lua 5.2, and Lua ++5.3. This does *not* make Lua 5.2 (or even Lua 5.1) entirely ++compatible with Lua 5.3, but it brings the API closer to that of Lua ++5.3. ++ ++It includes: ++ ++* _For writing Lua_: The Lua module `compat53`, which can be require'd ++ from Lua scripts and run in Lua 5.1, 5.2, and 5.3, including a ++ backport of the `utf8` module, the 5.3 `table` module, and the ++ string packing functions straight from the Lua 5.3 sources. ++* _For writing C_: A C header and file which can be linked to your ++ Lua module written in C, providing some functions from the C API ++ of Lua 5.3 that do not exist in Lua 5.2 or 5.1, making it easier to ++ write C code that compiles with all three versions of liblua. ++ ++## How to use it ++ ++### Lua module ++ ++```lua ++require("compat53") ++``` ++ ++`compat53` makes changes to your global environment and does not return ++a meaningful return value, so the usual idiom of storing the return of ++`require` in a local variable makes no sense. ++ ++When run under Lua 5.3, this module does nothing. ++ ++When run under Lua 5.2 or 5.1, it replaces some of your standard ++functions and adds new ones to bring your environment closer to that ++of Lua 5.3. It also tries to load the backported `utf8`, `table`, and ++string packing modules automatically. If unsuccessful, pure Lua ++versions of the new `table` functions are used as a fallback, and ++[Roberto's struct library][1] is tried for string packing. ++ ++#### Lua submodules ++ ++```lua ++local _ENV = require("compat53.module") ++if setfenv then setfenv(1, _ENV) end ++``` ++ ++The `compat53.module` module does not modify the global environment, ++and so it is safe to use in modules without affecting other Lua files. ++It is supposed to be set as the current environment (see above), i.e. ++cherry picking individual functions from this module is expressly ++*not* supported!). Not all features are available when using this ++module (e.g. yieldable (x)pcall support, string/file methods, etc.), ++so it is recommended to use plain `require("compat53")` whenever ++possible. ++ ++### C code ++ ++There are two ways of adding the C API compatibility functions/macros to ++your project: ++* If `COMPAT53_PREFIX` is *not* `#define`d, `compat-5.3.h` `#include`s ++ `compat-5.3.c`, and all functions are made `static`. You don't have to ++ compile/link/add `compat-5.3.c` yourself. This is useful for one-file ++ projects. ++* If `COMPAT53_PREFIX` is `#define`d, all exported functions are renamed ++ behind the scenes using this prefix to avoid linker conflicts with other ++ code using this package. This doesn't change the way you call the ++ compatibility functions in your code. You have to compile and link ++ `compat-5.3.c` to your project yourself. You can change the way the ++ functions are exported using the `COMPAT53_API` macro (e.g. if you need ++ some `__declspec` magic). While it is technically possible to use ++ the "lua" prefix (and it looks better in the debugger), this is ++ discouraged because LuaJIT has started to implement its own Lua 5.2+ ++ C API functions, and with the "lua" prefix you'd violate the ++ one-definition rule with recent LuaJIT versions. ++ ++## What's implemented ++ ++### Lua ++ ++* the `utf8` module backported from the Lua 5.3 sources ++* `string.pack`, `string.packsize`, and `string.unpack` from the Lua ++ 5.3 sources or from the `struct` module. (`struct` is not 100% ++ compatible to Lua 5.3's string packing!) (See [here][4]) ++* `math.maxinteger` and `math.mininteger`, `math.tointeger`, `math.type`, ++ and `math.ult` (see [here][5]) ++* `assert` accepts non-string error messages ++* `ipairs` respects `__index` metamethod ++* `table.move` ++* `table` library respects metamethods ++ ++For Lua 5.1 additionally: ++* `load` and `loadfile` accept `mode` and `env` parameters ++* `table.pack` and `table.unpack` ++* string patterns may contain embedded zeros (but see [here][6]) ++* `string.rep` accepts `sep` argument ++* `string.format` calls `tostring` on arguments for `%s` ++* `math.log` accepts base argument ++* `xpcall` takes additional arguments ++* `pcall` and `xpcall` can execute functions that yield (see ++ [here][22] for a possible problem with `coroutine.running`) ++* `pairs` respects `__pairs` metamethod (see [here][7]) ++* `rawlen` (but `#` still doesn't respect `__len` for tables) ++* `package.searchers` as alias for `package.loaders` ++* `package.searchpath` (see [here][8]) ++* `coroutine` functions dealing with the main coroutine (see ++ [here][22] for a possible problem with `coroutine.running`) ++* `coroutine.create` accepts functions written in C ++* return code of `os.execute` (see [here][9]) ++* `io.write` and `file:write` return file handle ++* `io.lines` and `file:lines` accept format arguments (like `io.read`) ++ (see [here][10] and [here][11]) ++* `debug.setmetatable` returns object ++* `debug.getuservalue` (see [here][12]) ++* `debug.setuservalue` (see [here][13]) ++ ++### C ++ ++* `lua_KContext` (see [here][14]) ++* `lua_KFunction` (see [here][14]) ++* `lua_dump` (extra `strip` parameter, ignored, see [here][15]) ++* `lua_getfield` (return value) ++* `lua_geti` and `lua_seti` ++* `lua_getglobal` (return value) ++* `lua_getmetafield` (return value) ++* `lua_gettable` (return value) ++* `lua_getuservalue` (limited compatibility, see [here][16]) ++* `lua_setuservalue` (limited compatibility, see [here][17]) ++* `lua_isinteger` ++* `lua_numbertointeger` ++* `lua_callk` and `lua_pcallk` (limited compatibility, see [here][14]) ++* `lua_resume` ++* `lua_rawget` and `lua_rawgeti` (return values) ++* `lua_rawgetp` and `lua_rawsetp` ++* `luaL_requiref` (now checks `package.loaded` first) ++* `lua_rotate` ++* `lua_stringtonumber` (see [here][18]) ++ ++For Lua 5.1 additionally: ++* `LUA_OK` ++* `LUA_ERRGCMM` ++* `LUA_OP*` macros for `lua_arith` and `lua_compare` ++* `LUA_FILEHANDLE` ++* `lua_Unsigned` ++* `luaL_Stream` (limited compatibility, see [here][19]) ++* `lua_absindex` ++* `lua_arith` (see [here][20]) ++* `lua_compare` ++* `lua_len`, `lua_rawlen`, and `luaL_len` ++* `lua_load` (mode argument) ++* `lua_pushstring`, `lua_pushlstring` (return value) ++* `lua_copy` ++* `lua_pushglobaltable` ++* `luaL_testudata` ++* `luaL_setfuncs`, `luaL_newlibtable`, and `luaL_newlib` ++* `luaL_setmetatable` ++* `luaL_getsubtable` ++* `luaL_traceback` ++* `luaL_execresult` ++* `luaL_fileresult` ++* `luaL_loadbufferx` ++* `luaL_loadfilex` ++* `luaL_checkversion` (with empty body, only to avoid compile errors, ++ see [here][21]) ++* `luaL_tolstring` ++* `luaL_buffinitsize`, `luaL_prepbuffsize`, and `luaL_pushresultsize` ++ (see [here][22]) ++* `lua_pushunsigned`, `lua_tounsignedx`, `lua_tounsigned`, ++ `luaL_checkunsigned`, `luaL_optunsigned`, if ++ `LUA_COMPAT_APIINTCASTS` is defined. ++ ++## What's not implemented ++ ++* bit operators ++* integer division operator ++* utf8 escape sequences ++* 64 bit integers ++* `coroutine.isyieldable` ++* Lua 5.1: `_ENV`, `goto`, labels, ephemeron tables, etc. See ++ [`lua-compat-5.2`][2] for a detailed list. ++* the following C API functions/macros: ++ * `lua_isyieldable` ++ * `lua_getextraspace` ++ * `lua_arith` (new operators missing) ++ * `lua_push(v)fstring` (new formats missing) ++ * `lua_upvalueid` (5.1) ++ * `lua_upvaluejoin` (5.1) ++ * `lua_version` (5.1) ++ * `lua_yieldk` (5.1) ++ ++## See also ++ ++* For Lua-5.2-style APIs under Lua 5.1, see [lua-compat-5.2][2], ++ which also is the basis for most of the code in this project. ++* For Lua-5.1-style APIs under Lua 5.0, see [Compat-5.1][3] ++ ++## Credits ++ ++This package contains code written by: ++ ++* [The Lua Team](http://www.lua.org) ++* Philipp Janda ([@siffiejoe](http://github.com/siffiejoe)) ++* Tomás Guisasola Gorham ([@tomasguisasola](http://github.com/tomasguisasola)) ++* Hisham Muhammad ([@hishamhm](http://github.com/hishamhm)) ++* Renato Maia ([@renatomaia](http://github.com/renatomaia)) ++* [@ThePhD](http://github.com/ThePhD) ++* [@Daurnimator](http://github.com/Daurnimator) ++ ++ ++ [1]: http://www.inf.puc-rio.br/~roberto/struct/ ++ [2]: http://github.com/keplerproject/lua-compat-5.2/ ++ [3]: http://keplerproject.org/compat/ ++ [4]: https://github.com/keplerproject/lua-compat-5.3/wiki/string_packing ++ [5]: https://github.com/keplerproject/lua-compat-5.3/wiki/math.type ++ [6]: https://github.com/keplerproject/lua-compat-5.3/wiki/pattern_matching ++ [7]: https://github.com/keplerproject/lua-compat-5.3/wiki/pairs ++ [8]: https://github.com/keplerproject/lua-compat-5.3/wiki/package.searchpath ++ [9]: https://github.com/keplerproject/lua-compat-5.3/wiki/os.execute ++ [10]: https://github.com/keplerproject/lua-compat-5.3/wiki/io.lines ++ [11]: https://github.com/keplerproject/lua-compat-5.3/wiki/file.lines ++ [12]: https://github.com/keplerproject/lua-compat-5.3/wiki/debug.getuservalue ++ [13]: https://github.com/keplerproject/lua-compat-5.3/wiki/debug.setuservalue ++ [14]: https://github.com/keplerproject/lua-compat-5.3/wiki/yieldable_c_functions ++ [15]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_dump ++ [16]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_getuservalue ++ [17]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_setuservalue ++ [18]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_stringtonumber ++ [19]: https://github.com/keplerproject/lua-compat-5.3/wiki/luaL_Stream ++ [20]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_arith ++ [21]: https://github.com/keplerproject/lua-compat-5.3/wiki/luaL_checkversion ++ [22]: https://github.com/keplerproject/lua-compat-5.3/wiki/luaL_Buffer ++ [23]: https://github.com/keplerproject/lua-compat-5.3/wiki/coroutine.running ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.1-1.rockspec luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.1-1.rockspec +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.1-1.rockspec 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.1-1.rockspec 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,31 @@ ++package = "compat53" ++version = "0.1-1" ++source = { ++ url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.1.zip", ++ dir = "lua-compat-5.3-0.1", ++} ++description = { ++ summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", ++ detailed = [[ ++ This is a small module that aims to make it easier to write Lua ++ code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. ++ It does *not* make Lua 5.2 (or even 5.1) entirely compatible ++ with Lua 5.3, but it brings the API closer to that of Lua 5.3. ++ ]], ++ homepage = "https://github.com/keplerproject/lua-compat-5.3", ++ license = "MIT" ++} ++dependencies = { ++ "lua >= 5.1, < 5.4", ++ --"struct" -- make Roberto's struct module optional ++} ++build = { ++ type = "builtin", ++ modules = { ++ ["compat53"] = "compat53.lua", ++ ["compat53.utf8"] = "lutf8lib.c", ++ ["compat53.table"] = "ltablib.c", ++ ["compat53.string"] = "lstrlib.c", ++ } ++} ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.2-1.rockspec luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.2-1.rockspec +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.2-1.rockspec 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.2-1.rockspec 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,32 @@ ++package = "compat53" ++version = "0.2-1" ++source = { ++ url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.2.zip", ++ dir = "lua-compat-5.3-0.2", ++} ++description = { ++ summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", ++ detailed = [[ ++ This is a small module that aims to make it easier to write Lua ++ code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. ++ It does *not* make Lua 5.2 (or even 5.1) entirely compatible ++ with Lua 5.3, but it brings the API closer to that of Lua 5.3. ++ ]], ++ homepage = "https://github.com/keplerproject/lua-compat-5.3", ++ license = "MIT" ++} ++dependencies = { ++ "lua >= 5.1, < 5.4", ++ --"struct" -- make Roberto's struct module optional ++} ++build = { ++ type = "builtin", ++ modules = { ++ ["compat53.init"] = "compat53/init.lua", ++ ["compat53.module"] = "compat53/module.lua", ++ ["compat53.utf8"] = "lutf8lib.c", ++ ["compat53.table"] = "ltablib.c", ++ ["compat53.string"] = "lstrlib.c", ++ } ++} ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.3-1.rockspec luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.3-1.rockspec +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.3-1.rockspec 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.3-1.rockspec 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,32 @@ ++package = "compat53" ++version = "0.3-1" ++source = { ++ url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.3.zip", ++ dir = "lua-compat-5.3-0.3", ++} ++description = { ++ summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", ++ detailed = [[ ++ This is a small module that aims to make it easier to write Lua ++ code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. ++ It does *not* make Lua 5.2 (or even 5.1) entirely compatible ++ with Lua 5.3, but it brings the API closer to that of Lua 5.3. ++ ]], ++ homepage = "https://github.com/keplerproject/lua-compat-5.3", ++ license = "MIT" ++} ++dependencies = { ++ "lua >= 5.1, < 5.4", ++ --"struct" -- make Roberto's struct module optional ++} ++build = { ++ type = "builtin", ++ modules = { ++ ["compat53.init"] = "compat53/init.lua", ++ ["compat53.module"] = "compat53/module.lua", ++ ["compat53.utf8"] = "lutf8lib.c", ++ ["compat53.table"] = "ltablib.c", ++ ["compat53.string"] = "lstrlib.c", ++ } ++} ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.4-1.rockspec luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.4-1.rockspec +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.4-1.rockspec 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.4-1.rockspec 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,32 @@ ++package = "compat53" ++version = "0.4-1" ++source = { ++ url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.4.zip", ++ dir = "lua-compat-5.3-0.4", ++} ++description = { ++ summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", ++ detailed = [[ ++ This is a small module that aims to make it easier to write Lua ++ code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. ++ It does *not* make Lua 5.2 (or even 5.1) entirely compatible ++ with Lua 5.3, but it brings the API closer to that of Lua 5.3. ++ ]], ++ homepage = "https://github.com/keplerproject/lua-compat-5.3", ++ license = "MIT" ++} ++dependencies = { ++ "lua >= 5.1, < 5.4", ++ --"struct" -- make Roberto's struct module optional ++} ++build = { ++ type = "builtin", ++ modules = { ++ ["compat53.init"] = "compat53/init.lua", ++ ["compat53.module"] = "compat53/module.lua", ++ ["compat53.utf8"] = "lutf8lib.c", ++ ["compat53.table"] = "ltablib.c", ++ ["compat53.string"] = "lstrlib.c", ++ } ++} ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.5-1.rockspec luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.5-1.rockspec +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.5-1.rockspec 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-0.5-1.rockspec 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,32 @@ ++package = "compat53" ++version = "0.5-1" ++source = { ++ url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.5.zip", ++ dir = "lua-compat-5.3-0.5", ++} ++description = { ++ summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", ++ detailed = [[ ++ This is a small module that aims to make it easier to write Lua ++ code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. ++ It does *not* make Lua 5.2 (or even 5.1) entirely compatible ++ with Lua 5.3, but it brings the API closer to that of Lua 5.3. ++ ]], ++ homepage = "https://github.com/keplerproject/lua-compat-5.3", ++ license = "MIT" ++} ++dependencies = { ++ "lua >= 5.1, < 5.4", ++ --"struct" -- make Roberto's struct module optional ++} ++build = { ++ type = "builtin", ++ modules = { ++ ["compat53.init"] = "compat53/init.lua", ++ ["compat53.module"] = "compat53/module.lua", ++ ["compat53.utf8"] = "lutf8lib.c", ++ ["compat53.table"] = "ltablib.c", ++ ["compat53.string"] = "lstrlib.c", ++ } ++} ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-scm-0.rockspec luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-scm-0.rockspec +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-scm-0.rockspec 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/rockspecs/compat53-scm-0.rockspec 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,32 @@ ++package = "compat53" ++version = "scm-0" ++source = { ++ url = "https://github.com/keplerproject/lua-compat-5.3/archive/master.zip", ++ dir = "lua-compat-5.3-master", ++} ++description = { ++ summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", ++ detailed = [[ ++ This is a small module that aims to make it easier to write Lua ++ code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. ++ It does *not* make Lua 5.2 (or even 5.1) entirely compatible ++ with Lua 5.3, but it brings the API closer to that of Lua 5.3. ++ ]], ++ homepage = "https://github.com/keplerproject/lua-compat-5.3", ++ license = "MIT" ++} ++dependencies = { ++ "lua >= 5.1, < 5.4", ++ --"struct" -- make Roberto's struct module optional ++} ++build = { ++ type = "builtin", ++ modules = { ++ ["compat53.init"] = "compat53/init.lua", ++ ["compat53.module"] = "compat53/module.lua", ++ ["compat53.utf8"] = "lutf8lib.c", ++ ["compat53.table"] = "ltablib.c", ++ ["compat53.string"] = "lstrlib.c", ++ } ++} ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/tests/test.lua luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/tests/test.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/tests/test.lua 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/tests/test.lua 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,819 @@ ++#!/usr/bin/env lua ++ ++local F, tproxy, writefile, noprint, ___ ++do ++ local type, unpack = type, table.unpack or unpack ++ local assert, io = assert, io ++ function F(...) ++ local args, n = { ... }, select('#', ...) ++ for i = 1, n do ++ local t = type(args[i]) ++ if t ~= "string" and t ~= "number" and t ~= "boolean" then ++ args[i] = t ++ end ++ end ++ return unpack(args, 1, n) ++ end ++ function tproxy(t) ++ return setmetatable({}, { ++ __index = t, ++ __newindex = t, ++ __len = function() return #t end, ++ }), t ++ end ++ function writefile(name, contents, bin) ++ local f = assert(io.open(name, bin and "wb" or "w")) ++ f:write(contents) ++ f:close() ++ end ++ function noprint() end ++ local sep = ("="):rep(70) ++ function ___() ++ print(sep) ++ end ++end ++ ++local V = _VERSION:gsub("^.*(%d+)%.(%d+)$", "%1%2") ++if jit then V = "jit" end ++ ++local mode = "global" ++if arg[1] == "module" then ++ mode = "module" ++end ++local self = arg[0] ++ ++package.path = "../?.lua;../?/init.lua" ++package.cpath = "./?-"..V..".so;./?-"..V..".dll;./?.so;./?.dll" ++if mode == "module" then ++ print("testing Lua API using `compat53.module` ...") ++ _ENV = require("compat53.module") ++ if setfenv then setfenv(1, _ENV) end ++else ++ print("testing Lua API using `compat53` ...") ++ require("compat53") ++end ++ ++ ++___'' ++do ++ print("assert", F(pcall(assert, false))) ++ print("assert", F(pcall(assert, false, nil))) ++ print("assert", F(pcall(assert, false, "error msg"))) ++ print("assert", F(pcall(assert, nil, {}))) ++ print("assert", F(pcall(assert, 1, 2, 3))) ++end ++ ++ ++___'' ++do ++ local t = setmetatable({}, { __index = { 1, false, "three" } }) ++ for i,v in ipairs(t) do ++ print("ipairs", i, v) ++ end ++end ++ ++ ++___'' ++do ++ local p, t = tproxy{ "a", "b", "c" } ++ print("table.concat", table.concat(p)) ++ print("table.concat", table.concat(p, ",", 2)) ++ print("table.concat", table.concat(p, ".", 1, 2)) ++ print("table.concat", table.concat(t)) ++ print("table.concat", table.concat(t, ",", 2)) ++ print("table.concat", table.concat(t, ".", 1, 2)) ++end ++ ++ ++___'' ++do ++ local p, t = tproxy{ "a", "b", "c" } ++ table.insert(p, "d") ++ print("table.insert", next(p), t[4]) ++ table.insert(p, 1, "z") ++ print("table.insert", next(p), t[1], t[2]) ++ table.insert(p, 2, "y") ++ print("table.insert", next(p), t[1], t[2], p[3]) ++ t = { "a", "b", "c" } ++ table.insert(t, "d") ++ print("table.insert", t[1], t[2], t[3], t[4]) ++ table.insert(t, 1, "z") ++ print("table.insert", t[1], t[2], t[3], t[4], t[5]) ++ table.insert(t, 2, "y") ++ print("table.insert", t[1], t[2], t[3], t[4], t[5]) ++end ++ ++ ++___'' ++do ++ local ps, s = tproxy{ "a", "b", "c", "d" } ++ local pd, d = tproxy{ "A", "B", "C", "D" } ++ table.move(ps, 1, 4, 1, pd) ++ print("table.move", next(pd), d[1], d[2], d[3], d[4]) ++ pd, d = tproxy{ "A", "B", "C", "D" } ++ table.move(ps, 2, 4, 1, pd) ++ print("table.move", next(pd), d[1], d[2], d[3], d[4]) ++ pd, d = tproxy{ "A", "B", "C", "D" } ++ table.move(ps, 2, 3, 4, pd) ++ print("table.move", next(pd), d[1], d[2], d[3], d[4], d[5]) ++ table.move(ps, 2, 4, 1) ++ print("table.move", next(ps), s[1], s[2], s[3], s[4]) ++ ps, s = tproxy{ "a", "b", "c", "d" } ++ table.move(ps, 2, 3, 4) ++ print("table.move", next(ps), s[1], s[2], s[3], s[4], s[5]) ++ s = { "a", "b", "c", "d" } ++ d = { "A", "B", "C", "D" } ++ table.move(s, 1, 4, 1, d) ++ print("table.move", d[1], d[2], d[3], d[4]) ++ d = { "A", "B", "C", "D" } ++ table.move(s, 2, 4, 1, d) ++ print("table.move", d[1], d[2], d[3], d[4]) ++ d = { "A", "B", "C", "D" } ++ table.move(s, 2, 3, 4, d) ++ print("table.move", d[1], d[2], d[3], d[4], d[5]) ++ table.move(s, 2, 4, 1) ++ print("table.move", s[1], s[2], s[3], s[4]) ++ s = { "a", "b", "c", "d" } ++ table.move(s, 2, 3, 4) ++ print("table.move", s[1], s[2], s[3], s[4], s[5]) ++end ++ ++ ++___'' ++do ++ local p, t = tproxy{ "a", "b", "c", "d", "e" } ++ print("table.remove", table.remove(p)) ++ print("table.remove", next(p), t[1], t[2], t[3], t[4], t[5]) ++ print("table.remove", table.remove(p, 1)) ++ print("table.remove", next(p), t[1], t[2], t[3], t[4]) ++ print("table.remove", table.remove(p, 2)) ++ print("table.remove", next(p), t[1], t[2], t[3]) ++ print("table.remove", table.remove(p, 3)) ++ print("table.remove", next(p), t[1], t[2], t[3]) ++ p, t = tproxy{} ++ print("table.remove", table.remove(p)) ++ print("table.remove", next(p), next(t)) ++ t = { "a", "b", "c", "d", "e" } ++ print("table.remove", table.remove(t)) ++ print("table.remove", t[1], t[2], t[3], t[4], t[5]) ++ print("table.remove", table.remove(t, 1)) ++ print("table.remove", t[1], t[2], t[3], t[4]) ++ print("table.remove", table.remove(t, 2)) ++ print("table.remove", t[1], t[2], t[3]) ++ print("table.remove", table.remove(t, 3)) ++ print("table.remove", t[1], t[2], t[3]) ++ t = {} ++ print("table.remove", table.remove(t)) ++ print("table.remove", next(t)) ++end ++ ++___'' ++do ++ local p, t = tproxy{ 3, 1, 5, 2, 8, 5, 2, 9, 7, 4 } ++ table.sort(p) ++ print("table.sort", next(p)) ++ for i,v in ipairs(t) do ++ print("table.sort", i, v) ++ end ++ table.sort(p) ++ print("table.sort", next(p)) ++ for i,v in ipairs(t) do ++ print("table.sort", i, v) ++ end ++ p, t = tproxy{ 9, 8, 7, 6, 5, 4, 3, 2, 1 } ++ table.sort(p) ++ print("table.sort", next(p)) ++ for i,v in ipairs(t) do ++ print("table.sort", i, v) ++ end ++ table.sort(p, function(a, b) return a > b end) ++ print("table.sort", next(p)) ++ for i,v in ipairs(t) do ++ print("table.sort", i, v) ++ end ++ p, t = tproxy{ 1, 1, 1, 1, 1 } ++ print("table.sort", next(p)) ++ for i,v in ipairs(t) do ++ print("table.sort", i, v) ++ end ++ t = { 3, 1, 5, 2, 8, 5, 2, 9, 7, 4 } ++ table.sort(t) ++ for i,v in ipairs(t) do ++ print("table.sort", i, v) ++ end ++ table.sort(t, function(a, b) return a > b end) ++ for i,v in ipairs(t) do ++ print("table.sort", i, v) ++ end ++end ++ ++ ++___'' ++do ++ local p, t = tproxy{ "a", "b", "c" } ++ print("table.unpack", table.unpack(p)) ++ print("table.unpack", table.unpack(p, 2)) ++ print("table.unpack", table.unpack(p, 1, 2)) ++ print("table.unpack", table.unpack(t)) ++ print("table.unpack", table.unpack(t, 2)) ++ print("table.unpack", table.unpack(t, 1, 2)) ++end ++ ++ ++___'' ++print("math.maxinteger", math.maxinteger+1 > math.maxinteger) ++print("math.mininteger", math.mininteger-1 < math.mininteger) ++ ++ ++___'' ++print("math.tointeger", math.tointeger(0)) ++print("math.tointeger", math.tointeger(math.pi)) ++print("math.tointeger", math.tointeger("hello")) ++print("math.tointeger", math.tointeger(math.maxinteger+2.0)) ++print("math.tointeger", math.tointeger(math.mininteger*2.0)) ++ ++ ++___'' ++print("math.type", math.type(0)) ++print("math.type", math.type(math.pi)) ++print("math.type", math.type("hello")) ++ ++ ++___'' ++print("math.ult", math.ult(1, 2), math.ult(2, 1)) ++print("math.ult", math.ult(-1, 2), math.ult(2, -1)) ++print("math.ult", math.ult(-1, -2), math.ult(-2, -1)) ++print("math.ult", pcall(math.ult, "x", 2)) ++print("math.ult", pcall(math.ult, 1, 2.1)) ++___'' ++ ++ ++if utf8.len then ++ local unpack = table.unpack or unpack ++ local function utf8rt(s) ++ local t = { utf8.codepoint(s, 1, #s) } ++ local ps, cs = {}, {} ++ for p,c in utf8.codes(s) do ++ ps[#ps+1], cs[#cs+1] = p, c ++ end ++ print("utf8.codes", unpack(ps)) ++ print("utf8.codes", unpack(cs)) ++ print("utf8.codepoint", unpack(t)) ++ print("utf8.len", utf8.len(s), #t, #s) ++ print("utf8.char", utf8.char(unpack(t))) ++ end ++ utf8rt("äöüßÄÖÜ") ++ utf8rt("abcdefg") ++ ___'' ++ local s = "äöüßÄÖÜ" ++ print("utf8.offset", utf8.offset(s, 1, 1)) ++ print("utf8.offset", utf8.offset(s, 2, 1)) ++ print("utf8.offset", utf8.offset(s, 3, 1)) ++ print("utf8.offset", pcall(utf8.offset, s, 3, 2)) ++ print("utf8.offset", utf8.offset(s, 3, 3)) ++ print("utf8.offset", utf8.offset(s, -1, 7)) ++ print("utf8.offset", utf8.offset(s, -2, 7)) ++ print("utf8.offset", utf8.offset(s, -3, 7)) ++ print("utf8.offset", utf8.offset(s, -1)) ++ ___'' ++else ++ print("XXX: utf8 module not available") ++end ++ ++ ++if string.pack then ++ local format = "bBhHlLjJdc3z" ++ local s = string.pack(format, -128, 255, -32768, 65535, -2147483648, 4294967295, -32768, 65536, 1.25, "abc", "defgh") ++ print("string.unpack", string.unpack(format, s)) ++ ___'' ++else ++ print("XXX: string packing not available") ++end ++ ++ ++print("testing Lua API for Lua 5.1 ...") ++ ++___'' ++print("debug.getuservalue()", F(debug.getuservalue(false))) ++print("debug.setuservalue()", pcall(function() ++ debug.setuservalue(false, {}) ++end)) ++print("debug.setmetatable()", F(debug.setmetatable({}, {}))) ++ ++ ++___'' ++do ++ local t = setmetatable({}, { ++ __pairs = function() return pairs({ a = "a" }) end, ++ }) ++ for k,v in pairs(t) do ++ print("pairs()", k, v) ++ end ++end ++ ++ ++___'' ++do ++ local code = "print('hello world')\n" ++ local badcode = "print('blub\n" ++ print("load()", pcall(function() load(true) end)) ++ print("load()", F(load(badcode))) ++ print("load()", F(load(code))) ++ print("load()", F(load(code, "[L]"))) ++ print("load()", F(load(code, "[L]", "b"))) ++ print("load()", F(load(code, "[L]", "t"))) ++ print("load()", F(load(code, "[L]", "bt"))) ++ local f = load(code, "[L]", "bt", {}) ++ print("load()", pcall(f)) ++ f = load(code, "[L]", "bt", { print = noprint }) ++ print("load()", pcall(f)) ++ local bytecode = string.dump(f) ++ print("load()", F(load(bytecode))) ++ print("load()", F(load(bytecode, "[L]"))) ++ print("load()", F(load(bytecode, "[L]", "b"))) ++ print("load()", F(load(bytecode, "[L]", "t"))) ++ print("load()", F(load(bytecode, "[L]", "bt"))) ++ f = load(bytecode, "[L]", "bt", {}) ++ print("load()", pcall(f)) ++ f = load(bytecode, "[L]", "bt", { print = noprint }) ++ print("load()", pcall(f)) ++ local function make_loader(code) ++ local mid = math.floor( #code/2 ) ++ local array = { code:sub(1, mid), code:sub(mid+1) } ++ local i = 0 ++ return function() ++ i = i + 1 ++ return array[i] ++ end ++ end ++ print("load()", F(load(make_loader(badcode)))) ++ print("load()", F(load(make_loader(code)))) ++ print("load()", F(load(make_loader(code), "[L]"))) ++ print("load()", F(load(make_loader(code), "[L]", "b"))) ++ print("load()", F(load(make_loader(code), "[L]", "t"))) ++ print("load()", F(load(make_loader(code), "[L]", "bt"))) ++ f = load(make_loader(code), "[L]", "bt", {}) ++ print("load()", pcall(f)) ++ f = load(make_loader(code), "[L]", "bt", { print = noprint }) ++ print("load()", pcall(f)) ++ print("load()", F(load(make_loader(bytecode)))) ++ print("load()", F(load(make_loader(bytecode), "[L]"))) ++ print("load()", F(load(make_loader(bytecode), "[L]", "b"))) ++ print("load()", F(load(make_loader(bytecode), "[L]", "t"))) ++ print("load()", F(load(make_loader(bytecode), "[L]", "bt"))) ++ f = load(make_loader(bytecode), "[L]", "bt", {}) ++ print("load()", pcall(f)) ++ f = load(make_loader(bytecode), "[L]", "bt", { print = noprint }) ++ print("load()", pcall(f)) ++ writefile("good.lua", code) ++ writefile("bad.lua", badcode) ++ writefile("good.luac", bytecode, true) ++ print("loadfile()", F(loadfile("bad.lua"))) ++ print("loadfile()", F(loadfile("good.lua"))) ++ print("loadfile()", F(loadfile("good.lua", "b"))) ++ print("loadfile()", F(loadfile("good.lua", "t"))) ++ print("loadfile()", F(loadfile("good.lua", "bt"))) ++ f = loadfile("good.lua", "bt", {}) ++ print("loadfile()", pcall(f)) ++ f = loadfile("good.lua", "bt", { print = noprint }) ++ print("loadfile()", pcall(f)) ++ print("loadfile()", F(loadfile("good.luac"))) ++ print("loadfile()", F(loadfile("good.luac", "b"))) ++ print("loadfile()", F(loadfile("good.luac", "t"))) ++ print("loadfile()", F(loadfile("good.luac", "bt"))) ++ f = loadfile("good.luac", "bt", {}) ++ print("loadfile()", pcall(f)) ++ f = loadfile("good.luac", "bt", { print = noprint }) ++ print("loadfile()", pcall(f)) ++ os.remove("good.lua") ++ os.remove("bad.lua") ++ os.remove("good.luac") ++end ++ ++ ++___'' ++do ++ local function func(throw) ++ if throw then ++ error("argh") ++ else ++ return 1, 2, 3 ++ end ++ end ++ local function tb(err) return "|"..err.."|" end ++ print("xpcall()", xpcall(func, debug.traceback, false)) ++ print("xpcall()", xpcall(func, debug.traceback, true)) ++ print("xpcall()", xpcall(func, tb, true)) ++ if mode ~= "module" then ++ local function func2(cb) ++ print("xpcall()", xpcall(cb, debug.traceback, "str")) ++ end ++ local function func3(cb) ++ print("pcall()", pcall(cb, "str")) ++ end ++ local function cb(arg) ++ coroutine.yield(2) ++ return arg ++ end ++ local c = coroutine.wrap(func2) ++ print("xpcall()", c(cb)) ++ print("xpcall()", c()) ++ local c = coroutine.wrap(func3) ++ print("pcall()", c(cb)) ++ print("pcall()", c()) ++ end ++end ++ ++ ++___'' ++do ++ local t = setmetatable({ 1 }, { __len = function() return 5 end }) ++ print("rawlen()", rawlen(t), rawlen("123")) ++end ++ ++ ++___'' ++print("os.execute()", os.execute("exit 1")) ++io.flush() ++print("os.execute()", os.execute("echo 'hello world!'")) ++io.flush() ++print("os.execute()", os.execute("no_such_file")) ++ ++ ++___'' ++do ++ local t = table.pack("a", nil, "b", nil) ++ print("table.(un)pack()", t.n, table.unpack(t, 1, t.n)) ++end ++ ++ ++___'' ++do ++ print("coroutine.running()", F(coroutine.wrap(function() ++ return coroutine.running() ++ end)())) ++ print("coroutine.running()", F(coroutine.running())) ++ local main_co, co1, co2 = coroutine.running() ++ -- coroutine.yield ++ if mode ~= "module" then ++ print("coroutine.yield()", pcall(function() ++ coroutine.yield(1, 2, 3) ++ end)) ++ end ++ print("coroutine.yield()", coroutine.wrap(function() ++ coroutine.yield(1, 2, 3) ++ end)()) ++ print("coroutine.resume()", coroutine.resume(main_co, 1, 2, 3)) ++ co1 = coroutine.create(function(a, b, c) ++ print("coroutine.resume()", a, b, c) ++ return a, b, c ++ end) ++ print("coroutine.resume()", coroutine.resume(co1, 1, 2, 3)) ++ co1 = coroutine.create(function() ++ print("coroutine.status()", "[co1] main is", coroutine.status(main_co)) ++ print("coroutine.status()", "[co1] co2 is", coroutine.status(co2)) ++ end) ++ co2 = coroutine.create(function() ++ print("coroutine.status()", "[co2] main is", coroutine.status(main_co)) ++ print("coroutine.status()", "[co2] co2 is", coroutine.status(co2)) ++ coroutine.yield() ++ coroutine.resume(co1) ++ end) ++ print("coroutine.status()", coroutine.status(main_co)) ++ print("coroutine.status()", coroutine.status(co2)) ++ coroutine.resume(co2) ++ print("coroutine.status()", F(coroutine.status(co2))) ++ coroutine.resume(co2) ++ print("coroutine.status()", F(coroutine.status(co2))) ++end ++ ++ ++___'' ++print("math.log()", math.log(1000)) ++print("math.log()", math.log(1000, 10)) ++ ++ ++___'' ++do ++ local path, prefix = "./?.lua;?/init.lua;../?.lua", "package.searchpath()" ++ print(prefix, package.searchpath("no.such.module", path)) ++ print(prefix, package.searchpath("no.such.module", "")) ++ print(prefix, package.searchpath("compat53", path)) ++ print(prefix, package.searchpath("no:such:module", path, ":", "|")) ++end ++ ++ ++___'' ++if mode ~= "module" then ++ local function mod_func() return {} end ++ local function my_searcher(name) ++ if name == "my.module" then ++ print("package.searchers", "my.module found") ++ return mod_func ++ end ++ end ++ local function my_searcher2(name) ++ if name == "my.module" then ++ print("package.searchers", "my.module found 2") ++ return mod_func ++ end ++ end ++ table.insert(package.searchers, my_searcher) ++ require("my.module") ++ package.loaded["my.module"] = nil ++ local new_s = { my_searcher2 } ++ for i,f in ipairs(package.searchers) do ++ new_s[i+1] = f ++ end ++ package.searchers = new_s ++ require("my.module") ++end ++ ++ ++___'' ++do ++ print("string.find()", string.find("abc\0abc\0abc", "[^a\0]+")) ++ print("string.find()", string.find("abc\0abc\0abc", "%w+\0", 5)) ++ for x in string.gmatch("abc\0def\0ghi", "[^\0]+") do ++ print("string.gmatch()", x) ++ end ++ for x in string.gmatch("abc\0def\0ghi", "%w*\0") do ++ print("string.gmatch()", #x) ++ end ++ print("string.gsub()", string.gsub("abc\0def\0ghi", "[\0]", "X")) ++ print("string.gsub()", string.gsub("abc\0def\0ghi", "%w*\0", "X")) ++ print("string.gsub()", string.gsub("abc\0def\0ghi", "%A", "X")) ++ print("string.match()", string.match("abc\0abc\0abc", "([^\0a]+)")) ++ print("string.match()", #string.match("abc\0abc\0abc", ".*\0")) ++ print("string.rep()", string.rep("a", 0)) ++ print("string.rep()", string.rep("b", 1)) ++ print("string.rep()", string.rep("c", 4)) ++ print("string.rep()", string.rep("a", 0, "|")) ++ print("string.rep()", string.rep("b", 1, "|")) ++ print("string.rep()", string.rep("c", 4, "|")) ++ local _tostring = tostring ++ function tostring(v) ++ if type(v) == "number" then ++ return "(".._tostring(v)..")" ++ else ++ return _tostring(v) ++ end ++ end ++ print("string.format()", string.format("%q", "\"\\\0000\0010\002\r\n0\t0\"")) ++ print("string.format()", string.format("%12.3fx%%sxx%.6s", 3.1, {})) ++ print("string.format()", string.format("%-3f %%%s %%s", 3.1, true)) ++ print("string.format()", string.format("% 3.2g %%d %%%s", 3.1, nil)) ++ print("string.format()", string.format("%+3d %%d %%%%%10.6s", 3, io.stdout)) ++ print("string.format()", pcall(function() ++ print("string.format()", string.format("%d %%s", {})) ++ end)) ++ tostring = _tostring ++end ++ ++ ++___'' ++do ++ print("io.write()", io.type(io.write("hello world\n"))) ++ local f = assert(io.tmpfile()) ++ print("file:write()", io.type(f:write("hello world\n"))) ++ f:close() ++end ++ ++ ++___'' ++do ++ writefile("data.txt", "123 18.8 hello world\ni'm here\n") ++ io.input("data.txt") ++ print("io.read()", io.read("*n", "*number", "*l", "*a")) ++ io.input("data.txt") ++ print("io.read()", io.read("n", "number", "l", "a")) ++ io.input(io.stdin) ++ if mode ~= "module" then ++ local f = assert(io.open("data.txt", "r")) ++ print("file:read()", f:read("*n", "*number", "*l", "*a")) ++ f:close() ++ f = assert(io.open("data.txt", "r")) ++ print("file:read()", f:read("n", "number", "l", "a")) ++ f:close() ++ end ++ os.remove("data.txt") ++end ++ ++ ++___'' ++do ++ writefile("data.txt", "123 18.8 hello world\ni'm here\n") ++ for a,b in io.lines(self, 2, "*l") do ++ print("io.lines()", a, b) ++ break ++ end ++ for l in io.lines(self) do ++ print("io.lines()", l) ++ break ++ end ++ for n1,n2,rest in io.lines("data.txt", "*n", "n", "*a") do ++ print("io.lines()", n1, n2, rest) ++ end ++ for l in io.lines("data.txt") do ++ print("io.lines()", l) ++ end ++ print("io.lines()", pcall(function() ++ for l in io.lines("data.txt", "*x") do print(l) end ++ end)) ++ print("io.lines()", pcall(function() ++ for l in io.lines("no_such_file.txt") do print(l) end ++ end)) ++ if mode ~= "module" then ++ local f = assert(io.open(self, "r")) ++ for a,b in f:lines(2, "*l") do ++ print("file:lines()", a, b) ++ break ++ end ++ f:close() ++ f = assert(io.open("data.txt", "r")) ++ for n1,n2,rest in f:lines("*n", "n", "*a") do ++ print("file:lines()", n1, n2, rest) ++ end ++ f:close() ++ f = assert(io.open("data.txt", "r")) ++ for l in f:lines() do ++ print("file:lines()", l) ++ end ++ f:close() ++ print("file:lines()", pcall(function() ++ for l in f:lines() do print(l) end ++ end)) ++ print("file:lines()", pcall(function() ++ local f = assert(io.open("data.txt", "r")) ++ for l in f:lines("*l", "*x") do print(l) end ++ f:close() ++ end)) ++ end ++ os.remove("data.txt") ++end ++___'' ++ ++ ++print("testing C API ...") ++local mod = require("testmod") ++___'' ++print("isinteger", mod.isinteger(1)) ++print("isinteger", mod.isinteger(0)) ++print("isinteger", mod.isinteger(1234567)) ++print("isinteger", mod.isinteger(12.3)) ++print("isinteger", mod.isinteger(math.huge)) ++print("isinteger", mod.isinteger(math.sqrt(-1))) ++ ++ ++___'' ++print("rotate", mod.rotate(1, 1, 2, 3, 4, 5, 6)) ++print("rotate", mod.rotate(-1, 1, 2, 3, 4, 5, 6)) ++print("rotate", mod.rotate(4, 1, 2, 3, 4, 5, 6)) ++print("rotate", mod.rotate(-4, 1, 2, 3, 4, 5, 6)) ++ ++ ++___'' ++print("strtonum", mod.strtonum("+123")) ++print("strtonum", mod.strtonum(" 123 ")) ++print("strtonum", mod.strtonum("-1.23")) ++print("strtonum", mod.strtonum(" 123 abc")) ++print("strtonum", mod.strtonum("jkl")) ++ ++ ++___'' ++local a, b, c = mod.requiref() ++print("requiref", type(a), type(b), type(c), ++ a.boolean, b.boolean, c.boolean, ++ type(requiref1), type(requiref2), type(requiref3)) ++ ++___'' ++local proxy, backend = {}, {} ++setmetatable(proxy, { __index = backend, __newindex = backend }) ++print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) ++print("geti/seti", mod.getseti(proxy, 1)) ++print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) ++print("geti/seti", mod.getseti(proxy, 1)) ++print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) ++ ++-- tests for Lua 5.1 ++___'' ++print("tonumber", mod.tonumber(12)) ++print("tonumber", mod.tonumber("12")) ++print("tonumber", mod.tonumber("0")) ++print("tonumber", mod.tonumber(false)) ++print("tonumber", mod.tonumber("error")) ++ ++___'' ++print("tointeger", mod.tointeger(12)) ++print("tointeger", mod.tointeger(-12)) ++print("tointeger", mod.tointeger(12.1)) ++print("tointeger", mod.tointeger(12.9)) ++print("tointeger", mod.tointeger(-12.1)) ++print("tointeger", mod.tointeger(-12.9)) ++print("tointeger", mod.tointeger("12")) ++print("tointeger", mod.tointeger("0")) ++print("tointeger", mod.tointeger(math.pi)) ++print("tointeger", mod.tointeger(false)) ++print("tointeger", mod.tointeger("error")) ++ ++___'' ++print("len", mod.len("123")) ++print("len", mod.len({ 1, 2, 3})) ++print("len", pcall(mod.len, true)) ++local ud, meta = mod.newproxy() ++meta.__len = function() return 5 end ++print("len", mod.len(ud)) ++meta.__len = function() return true end ++print("len", pcall(mod.len, ud)) ++ ++___'' ++print("copy", mod.copy(true, "string", {}, 1)) ++ ++___'' ++print("rawgetp/rawsetp", mod.rawxetp()) ++print("rawgetp/rawsetp", mod.rawxetp("I'm back")) ++ ++___'' ++print("globals", F(mod.globals()), mod.globals() == _G) ++ ++___'' ++local t = {} ++print("getsubtable", F(mod.subtable(t))) ++local x, msg = mod.subtable(t) ++print("getsubtable", F(x, msg, x == t.xxx)) ++ ++___'' ++print("udata", F(mod.udata())) ++print("udata", mod.udata("nosuchtype")) ++ ++___'' ++print("uservalue", F(mod.uservalue())) ++ ++___'' ++print("upvalues", mod.getupvalues()) ++ ++___'' ++print("absindex", mod.absindex("hi", true)) ++ ++___'' ++print("arith", mod.arith(2, 1)) ++print("arith", mod.arith(3, 5)) ++ ++___'' ++print("compare", mod.compare(1, 1)) ++print("compare", mod.compare(2, 1)) ++print("compare", mod.compare(1, 2)) ++ ++___'' ++print("tolstring", mod.tolstring("string")) ++local t = setmetatable({}, { ++ __tostring = function(v) return "mytable" end ++}) ++print("tolstring", mod.tolstring(t)) ++local t = setmetatable({}, { ++ __tostring = function(v) return nil end ++}) ++print("tolstring", pcall(mod.tolstring, t)) ++local ud, meta = mod.newproxy() ++meta.__name = "XXX" ++print("tolstring", mod.tolstring(ud):gsub(":.*$", ": yyy")) ++ ++___'' ++print("pushstring", mod.pushstring()) ++ ++___'' ++print("Buffer", mod.buffer()) ++ ++___'' ++print("execresult", mod.exec("exit 0")) ++print("execresult", mod.exec("exit 1")) ++print("execresult", mod.exec("exit 25")) ++ ++___'' ++do ++ local bin = string.dump(function() end) ++ local modes = { "t", "b", "bt" } ++ local codes = { ++ "", "return true", bin, "invalidsource", "\27invalidbinary" ++ } ++ for _,m in ipairs(modes) do ++ for i,c in ipairs(codes) do ++ print("loadbufferx", m, i, F(mod.loadstring(c, m))) ++ end ++ end ++ ++ ___'' ++ local bom = "\239\187\191" ++ local shebang = "#!/usr/bin/env lua\n" ++ codes[#codes+1] = bom .. shebang .. "return true" ++ codes[#codes+1] = bom .. shebang .. bin ++ codes[#codes+1] = bom .. shebang .. "invalidsource" ++ codes[#codes+1] = bom .. shebang .. "\027invalidbinary" ++ for _,m in ipairs(modes) do ++ for i,c in ipairs(codes) do ++ print("loadfilex", m, i, F(mod.loadfile(c, m))) ++ end ++ end ++end ++___'' ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/tests/testmod.c luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/tests/testmod.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/tests/testmod.c 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/tests/testmod.c 2019-02-13 11:53:29.078405237 +0100 +@@ -0,0 +1,352 @@ ++#include ++#include ++#include "compat-5.3.h" ++ ++ ++static int test_isinteger (lua_State *L) { ++ lua_pushboolean(L, lua_isinteger(L, 1)); ++ return 1; ++} ++ ++ ++static int test_rotate (lua_State *L) { ++ int r = (int)luaL_checkinteger(L, 1); ++ int n = lua_gettop(L)-1; ++ luaL_argcheck(L, (r < 0 ? -r : r) <= n, 1, "not enough arguments"); ++ lua_rotate(L, 2, r); ++ return n; ++} ++ ++ ++static int test_str2num (lua_State *L) { ++ const char *s = luaL_checkstring(L, 1); ++ size_t len = lua_stringtonumber(L, s); ++ if (len == 0) ++ lua_pushnumber(L, 0); ++ lua_pushinteger(L, (lua_Integer)len); ++ return 2; ++} ++ ++ ++static int my_mod (lua_State *L ) { ++ lua_newtable(L); ++ lua_pushboolean(L, 1); ++ lua_setfield(L, -2, "boolean"); ++ return 1; ++} ++ ++static int test_requiref (lua_State *L) { ++ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); ++ lua_newtable(L); ++ lua_pushboolean(L, 0); ++ lua_setfield(L, -2, "boolean"); ++ lua_setfield(L, -2, "requiref3"); ++ lua_pop(L, 1); ++ luaL_requiref(L, "requiref1", my_mod, 0); ++ luaL_requiref(L, "requiref2", my_mod, 1); ++ luaL_requiref(L, "requiref3", my_mod, 1); ++ return 3; ++} ++ ++static int test_getseti (lua_State *L) { ++ lua_Integer k = luaL_checkinteger(L, 2); ++ lua_Integer n = 0; ++ if (lua_geti(L, 1, k) == LUA_TNUMBER) { ++ n = lua_tointeger(L, -1); ++ } else { ++ lua_pop(L, 1); ++ lua_pushinteger(L, n); ++ } ++ lua_pushinteger(L, n+1); ++ lua_seti(L, 1, k); ++ return 1; ++} ++ ++ ++/* additional tests for Lua5.1 */ ++#define NUP 3 ++ ++static int test_newproxy (lua_State *L) { ++ lua_settop(L, 0); ++ lua_newuserdata(L, 0); ++ lua_newtable(L); ++ lua_pushvalue(L, -1); ++ lua_pushboolean(L, 1); ++ lua_setfield(L, -2, "__gc"); ++ lua_setmetatable(L, -3); ++ return 2; ++} ++ ++static int test_absindex (lua_State *L) { ++ int i = 1; ++ for (i = 1; i <= NUP; ++i) ++ lua_pushvalue(L, lua_absindex(L, lua_upvalueindex(i))); ++ lua_pushvalue(L, lua_absindex(L, LUA_REGISTRYINDEX)); ++ lua_pushstring(L, lua_typename(L, lua_type(L, lua_absindex(L, -1)))); ++ lua_replace(L, lua_absindex(L, -2)); ++ lua_pushvalue(L, lua_absindex(L, -2)); ++ lua_pushvalue(L, lua_absindex(L, -4)); ++ lua_pushvalue(L, lua_absindex(L, -6)); ++ i += 3; ++ lua_pushvalue(L, lua_absindex(L, 1)); ++ lua_pushvalue(L, lua_absindex(L, 2)); ++ lua_pushvalue(L, lua_absindex(L, 3)); ++ i += 3; ++ return i; ++} ++ ++static int test_arith (lua_State *L) { ++ lua_settop(L, 2); ++ lua_pushvalue(L, 1); ++ lua_pushvalue(L, 2); ++ lua_arith(L, LUA_OPADD); ++ lua_pushvalue(L, 1); ++ lua_pushvalue(L, 2); ++ lua_arith(L, LUA_OPSUB); ++ lua_pushvalue(L, 1); ++ lua_pushvalue(L, 2); ++ lua_arith(L, LUA_OPMUL); ++ lua_pushvalue(L, 1); ++ lua_pushvalue(L, 2); ++ lua_arith(L, LUA_OPDIV); ++ lua_pushvalue(L, 1); ++ lua_pushvalue(L, 2); ++ lua_arith(L, LUA_OPMOD); ++ lua_pushvalue(L, 1); ++ lua_pushvalue(L, 2); ++ lua_arith(L, LUA_OPPOW); ++ lua_pushvalue(L, 1); ++ lua_arith(L, LUA_OPUNM); ++ return lua_gettop(L)-2; ++} ++ ++static int test_compare (lua_State *L) { ++ luaL_checknumber(L, 1); ++ luaL_checknumber(L, 2); ++ lua_settop(L, 2); ++ lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPEQ)); ++ lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLT)); ++ lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLE)); ++ return 3; ++} ++ ++static int test_globals (lua_State *L) { ++ lua_pushglobaltable(L); ++ return 1; ++} ++ ++static int test_tonumber (lua_State *L) { ++ int isnum = 0; ++ lua_Number n = lua_tonumberx(L, 1, &isnum); ++ if (!isnum) ++ lua_pushnil(L); ++ else ++ lua_pushnumber(L, n); ++ return 1; ++} ++ ++static int test_tointeger (lua_State *L) { ++ int isnum = 0; ++ lua_Integer n = lua_tointegerx(L, 1, &isnum); ++ if (!isnum) ++ lua_pushnil(L); ++ else ++ lua_pushinteger(L, n); ++ lua_pushinteger(L, lua_tointeger(L, 1)); ++ return 2; ++} ++ ++static int test_len (lua_State *L) { ++ luaL_checkany(L, 1); ++ lua_len(L, 1); ++ lua_pushinteger(L, luaL_len(L, 1)); ++ return 2; ++} ++ ++static int test_copy (lua_State *L) { ++ int args = lua_gettop(L); ++ if (args >= 2) { ++ int i = 0; ++ for (i = args-1; i > 0; --i) ++ lua_copy(L, args, i); ++ } ++ return args; ++} ++ ++/* need an address */ ++static char const dummy = 0; ++ ++static int test_rawxetp (lua_State *L) { ++ if (lua_gettop(L) > 0) ++ lua_pushvalue(L, 1); ++ else ++ lua_pushliteral(L, "hello again"); ++ lua_rawsetp(L, LUA_REGISTRYINDEX, &dummy); ++ lua_settop(L, 0); ++ lua_rawgetp(L, LUA_REGISTRYINDEX, &dummy); ++ return 1; ++} ++ ++static int test_udata (lua_State *L) { ++ const char *tname = luaL_optstring(L, 1, "utype1"); ++ void *u1 = lua_newuserdata(L, 1); ++ int u1pos = lua_gettop(L); ++ void *u2 = lua_newuserdata(L, 1); ++ int u2pos = lua_gettop(L); ++ luaL_newmetatable(L, "utype1"); ++ luaL_newmetatable(L, "utype2"); ++ lua_pop(L, 2); ++ luaL_setmetatable(L, "utype2"); ++ lua_pushvalue(L, u1pos); ++ luaL_setmetatable(L, "utype1"); ++ lua_pop(L, 1); ++ (void)u1; ++ (void)u2; ++ lua_pushlightuserdata(L, luaL_testudata(L, u1pos, tname)); ++ lua_pushlightuserdata(L, luaL_testudata(L, u2pos, tname)); ++ luaL_getmetatable(L, "utype1"); ++ lua_getfield(L, -1, "__name"); ++ lua_replace(L, -2); ++ return 3; ++} ++ ++static int test_subtable (lua_State *L) { ++ luaL_checktype(L, 1, LUA_TTABLE); ++ lua_settop(L, 1); ++ if (luaL_getsubtable(L, 1, "xxx")) { ++ lua_pushliteral(L, "oldtable"); ++ } else { ++ lua_pushliteral(L, "newtable"); ++ } ++ return 2; ++} ++ ++static int test_uservalue (lua_State *L) { ++ void *udata = lua_newuserdata(L, 1); ++ int ui = lua_gettop(L); ++ lua_newtable(L); ++ lua_setuservalue(L, ui); ++ lua_pushinteger(L, lua_getuservalue(L, ui)); ++ (void)udata; ++ return 2; ++} ++ ++static int test_upvalues (lua_State *L) { ++ int i = 1; ++ for (i = 1; i <= NUP; ++i) ++ lua_pushvalue(L, lua_upvalueindex(i)); ++ return NUP; ++} ++ ++static int test_tolstring (lua_State *L) { ++ size_t len = 0; ++ luaL_tolstring(L, 1, &len); ++ lua_pushinteger(L, (int)len); ++ return 2; ++} ++ ++static int test_pushstring (lua_State *L) { ++ lua_pushstring(L, lua_pushliteral(L, "abc")); ++ lua_pushstring(L, lua_pushlstring(L, "abc", 2)); ++ lua_pushstring(L, lua_pushlstring(L, NULL, 0)); ++ lua_pushstring(L, lua_pushstring(L, "abc")); ++ lua_pushboolean(L, NULL == lua_pushstring(L, NULL)); ++ return 10; ++} ++ ++static int test_buffer (lua_State *L) { ++ luaL_Buffer b; ++ char *p = luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE+1); ++ p[0] = 'a'; ++ p[1] = 'b'; ++ luaL_addsize(&b, 2); ++ luaL_addstring(&b, "c"); ++ lua_pushliteral(L, "d"); ++ luaL_addvalue(&b); ++ luaL_addchar(&b, 'e'); ++ luaL_pushresult(&b); ++ return 1; ++} ++ ++static int test_exec (lua_State *L) { ++ const char *cmd = luaL_checkstring(L, 1); ++ return luaL_execresult(L, system(cmd)); ++} ++ ++static int test_loadstring (lua_State *L) { ++ size_t len = 0; ++ char const* s = luaL_checklstring(L, 1, &len); ++ char const* mode = luaL_optstring(L, 2, "bt"); ++ lua_pushinteger(L, luaL_loadbufferx(L, s, len, s, mode)); ++ return 2; ++} ++ ++static int test_loadfile (lua_State *L) { ++ char filename[L_tmpnam+1] = { 0 }; ++ size_t len = 0; ++ char const* s = luaL_checklstring(L, 1, &len); ++ char const* mode = luaL_optstring(L, 2, "bt"); ++ if (tmpnam(filename)) { ++ FILE* f = fopen(filename, "wb"); ++ if (f) { ++ fwrite(s, 1, len, f); ++ fclose(f); ++ lua_pushinteger(L, luaL_loadfilex(L, filename, mode)); ++ remove(filename); ++ return 2; ++ } else ++ remove(filename); ++ } ++ return 0; ++} ++ ++ ++static const luaL_Reg funcs[] = { ++ { "isinteger", test_isinteger }, ++ { "rotate", test_rotate }, ++ { "strtonum", test_str2num }, ++ { "requiref", test_requiref }, ++ { "getseti", test_getseti }, ++ { "newproxy", test_newproxy }, ++ { "arith", test_arith }, ++ { "compare", test_compare }, ++ { "tonumber", test_tonumber }, ++ { "tointeger", test_tointeger }, ++ { "len", test_len }, ++ { "copy", test_copy }, ++ { "rawxetp", test_rawxetp }, ++ { "subtable", test_subtable }, ++ { "udata", test_udata }, ++ { "uservalue", test_uservalue }, ++ { "globals", test_globals }, ++ { "tolstring", test_tolstring }, ++ { "pushstring", test_pushstring }, ++ { "buffer", test_buffer }, ++ { "exec", test_exec }, ++ { "loadstring", test_loadstring }, ++ { "loadfile", test_loadfile }, ++ { NULL, NULL } ++}; ++ ++static const luaL_Reg more_funcs[] = { ++ { "getupvalues", test_upvalues }, ++ { "absindex", test_absindex }, ++ { NULL, NULL } ++}; ++ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++int luaopen_testmod (lua_State *L) { ++ int i = 1; ++ luaL_newlib(L, funcs); ++ for (i = 1; i <= NUP; ++i) ++ lua_pushnumber(L, i); ++ luaL_setfuncs(L, more_funcs, NUP); ++ return 1; ++} ++#ifdef __cplusplus ++} ++#endif ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/.travis.yml luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/.travis.yml +--- luvi-src-v2.7.6.orig/deps/lua-openssl/deps/lua-compat/.travis.yml 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/deps/lua-compat/.travis.yml 2019-02-13 11:53:29.075071941 +0100 +@@ -0,0 +1,47 @@ ++language: c ++compiler: gcc ++ ++sudo: false ++ ++env: ++ - LUA="lua=5.1" ++ - LUA="lua=5.1" EXTERNAL=true ++ - LUA="lua=5.1" COMPILER="g++" ++ - LUA="lua=5.1" EXTERNAL=true COMPILER="g++" ++ - LUA="luajit=@v2.1 --compat=none" ++ - LUA="luajit=@v2.1 --compat=none" EXTERNAL=true ++ - LUA="luajit=@v2.1 --compat=all" ++ - LUA="luajit=@v2.1 --compat=all" EXTERNAL=true ++ - LUA="lua=5.2" ++ - LUA="lua=5.2" EXTERNAL=true ++ - LUA="lua=5.2" COMPILER="g++" ++ - LUA="lua=5.2" EXTERNAL=true COMPILER="g++" ++ ++branches: ++ only: ++ - master ++ ++git: ++ depth: 3 ++ ++notifications: ++ email: false ++ ++before_install: ++ - pip install --user hererocks ++ - hererocks old --$LUA ++ - test -e old/bin/lua || (cd old/bin && ln -s luajit* lua) ++ - hererocks new --lua=5.3 ++ ++install: ++ - export CC="${COMPILER:-gcc}" DEF="" SRC="" CFLAGS="-Wall -Wextra -Ic-api -O2 -fPIC" ++ - if [ "x${EXTERNAL:-}" = xtrue ]; then DEF="-DCOMPAT53_PREFIX=compat53" SRC="c-api/compat-5.3.c"; fi ++ - ${CC} ${CFLAGS} -Iold/include ${DEF} -shared -o old/testmod.so tests/testmod.c ${SRC} ++ - ${CC} ${CFLAGS} -Inew/include ${DEF} -shared -o new/testmod.so tests/testmod.c ${SRC} ++ - gcc ${CFLAGS} -Iold/include ${DEF} -shared -o old/compat53.so ltablib.c lutf8lib.c lstrlib.c ${SRC} ++ ++script: ++ - (cd old && bin/lua ../tests/test.lua) > old.txt ++ - (cd new && bin/lua ../tests/test.lua) > new.txt ++ - diff old.txt new.txt || true ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/asn1.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/asn1.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/asn1.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/asn1.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,209 +0,0 @@ +---- +--- Provide asn1_object, asn1_string, asn1_object as lua object. +--- Sometime when you want to custome x509, you maybe need to use this. +--- +--- @module asn1 +--- @usage +--- asn1 = require('openssl').asn1 +--- +- +-do -- define module function +- +---- Create asn1_object object +--- +--- @tparam string name_or_oid short name,long name or oid string +--- @tparam[opt] boolean no_name true for only oid string, default is false +--- @treturn asn1_object mapping to ASN1_OBJECT in openssl +--- +--- @see asn1_object +-function new_object() end +- +---- Create asn1_object object +--- +--- @tparam integer nid ident to asn1_object +--- @treturn asn1_object mapping to ASN1_OBJECT in openssl +--- +--- @see asn1_object +-function new_object() end +- +---- Create asn1_object object +--- +--- @tparam table options have sn, ln, oid keys to create asn1_object +--- @treturn asn1_object mapping to ASN1_OBJECT in openssl +--- +--- @see asn1_object +-function new_object() end +- +---- Create asn1_string object +--- +---

asn1_string object support types: "integer", "enumerated", "bit", "octet", "utf8", +--- "numeric", "printable", "t61", "teletex", "videotex", "ia5", "graphics", "iso64", +--- "visible", "general", "unversal", "bmp", "utctime"

+--- +--- @tparam string data to create new asn1_string +--- @tparam[opt] string type asn1 string type, defult with 'utf8' +--- @see asn1_string +-function new_string() end +- +---- get nid for txt, which can be short name, long name, or numerical oid +--- +--- @tparam string txt which get to nid +--- @treturn integer nid or nil on fail +-function txt2nid() end +- +---- make tag, class number to string +--- +--- @tparam number clsortag which to string +--- @tparam string range only accept 'class' or 'tag' +-function tostring() end +- +---- parse der encoded string +--- @tparam string der string +--- @tparam[opt=1] number start offset to parse +--- @tparam[opt=-i] number stop offset to parse +--- this like string.sub() +--- @treturn[1] number tag +--- @treturn[1] number class +--- @treturn[1] number parsed data start offset +--- @treturn[1] number parsed data stop offset +--- @treturn[1] boolean true for constructed data +--- @treturn[2] nil for fail +--- @treturn[2] string error msg +--- @treturn[2] number inner error code +-function get_object() end +- +---- do der encode and return encoded string partly head or full +--- @tparam number tag +--- @tparam number class +--- @tparam[opt=nil] number|string length or date to encode, defualt will make +--- indefinite length constructed +--- @tparam[opt=nil] boolean constructed or not +--- @treturn string der encoded string or head when not give data +-function put_object() end +- +-end +- +-do -- define class +- +---- openssl.asn1_object object +--- @type asn1_object +--- +-do -- defint asn1_object +- +---- get nid of asn1_object. +--- +--- @treturn integer nid of asn1_object +--- +-function nid() end +- +---- get name of asn1_object. +--- +--- @treturn string short name of asn1_object +--- @treturn string long name of asn1_object +--- +-function name() end +- +---- get short name of asn1_object. +--- +--- @treturn string short name of asn1_object +--- +-function sn() end +- +---- get long name of asn1_object. +--- +--- @treturn string long name of asn1_object +--- +-function ln() end +- +---- get text of asn1_object. +--- +--- @tparam[opt] boolean no_name true for only oid or name, default with false +--- @treturn string long or short name, even oid of asn1_object +--- +-function txt() end +- +---- compare two asn1_objects, if equals return true +--- +--- @tparam asn1_object another to compre +--- @treturn boolean true if equals +--- +-function __eq(another) end +- +---- make a clone of asn1_object +--- +--- @treturn asn1_object clone for self +-function dup() end +- +---- get data of asn1_object +--- +--- @treturn string asn1_object data +-function data() end +- +-end +- +- +---- openssl.asn1_string object +--- @type asn1_string +- +-do +- +---- get type of asn1_string +--- +--- @treturn string type of asn1_string +--- @see new_string +-function type() end +- +---- get data of asn1_string +--- +--- @treturn string raw data of asn1_string +-function data() end +- +---- set data of asn1_string +--- +--- @tparam string data set to asn1_string +--- @treturn boolean success if value set true, or follow by errmsg +--- @treturn string fail error message +-function data() end +- +---- get data as utf8 encode string +--- +--- @treturn string utf8 encoded string +-function toutf8() end +- +---- get data as printable encode string +--- +--- @treturn string printable encoded string +-function print() end +- +---- duplicate a new asn1_string +--- +--- @treturn asn1_string clone for self +-function dup() end +- +---- get length two asn1_string +--- +--- @treturn integer length of asn1_string +--- @usage +--- local astr = asn1.new_string('ABCD') +--- print('length:',#astr) +--- print('length:',astr:length()) +--- assert(#astr==astr:length,"must equals") +-function length() end +- +---- compare two asn1_string, if equals return true +--- +--- @tparam asn1_string another to compre +--- @treturn boolean true if equals +--- @usage +--- local obj = astr:dup() +--- assert(obj==astr, "must equals") +-function __eq(another) end +- +---- convert asn1_string to lua string +--- +--- @treturn string result format match with type:data +-function __tostring() end +- +-end +- +-end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/bio.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/bio.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/bio.lua 2019-02-13 11:31:40.283968667 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/bio.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,147 +0,0 @@ +------------- +--- Provide bio module. +--- bio object mapping to BIO in openssl +--- openssl.bio is a help object, it is useful, but rarely use. +--- @module bio +--- @usage +--- bio = require'openssl'.bio +- +-do --define module function +- +---- make string as bio object +--- same with bio.mem, implication by metatable '__call' +--- @tparam[opt=nil] string data +--- @treturn bio +-function openssl.bio() end +- +---- make string as bio object +--- @tparam[opt=nil] string data, it will be memory buffer data +--- @treturn bio it can be input or output object +-function mem() end +- +---- make tcp bio from socket fd +--- @tparam number fd +--- @tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc +--- @treturn bio +-function socket() end +- +---- make dgram bio from socket fd +--- @tparam number fd +--- @tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc +--- @treturn bio +-function dgram() end +- +---- make socket or file bio with fd +--- @tparam number fd +--- @tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc +--- @treturn bio +-function fd() end +- +---- make file object with file name or path +--- @tparam string file +--- @tparam[opt='r'] string mode +--- @treturn bio +-function file() end +- +---- make tcp client socket +--- @tparam string host_addr addrees like 'host:port' +--- @tparam[opt=true] boolean connect default connect immediately +--- @treturn bio +-function connect() end +- +---- make tcp listen socket +--- @tparam string host_port address like 'host:port' +--- @treturn bio +-function accept() end +- +---- Create base64 or buffer bio, which can append to an io BIO object +--- @tparam string mode support 'base64' or 'buffer' +--- @treturn bio +-function filter() end +- +---- Create digest bio, which can append to an io BIO object +--- @tparam string mode must be 'digest' +--- @tparam evp_md|string md_alg +--- @treturn bio +-function filter() end +- +---- Create ssl bio +--- @tparam string mode must be 'ssl' +--- @tparam ssl s +--- @tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc +--- @treturn bio +-function filter() end +- +---- create cipher filter bio object +--- @tparam string mode must be 'cipher' +--- @tparam string key +--- @tparam string iv +--- @tparam[opt=true] boolean encrypt +--- @treturn bio +-function filter() end +- +-end -- define module +- +- +-do -- define class +- +---- openssl.bio object +--- @type bio +--- +- +-do -- define bio +- +---- setup ready and accept client connect +--- @tparam[opt=false] boolean setup true for setup accept bio, false or none will accept client connect +--- @treturn[1] boolean result only when setup is true +--- @treturn[2] bio accpeted bio object +-function accept() end +- +---- read data from bio object +--- @tparam number len +--- @treturn string string length may be less than param len +-function read() end +- +---- get line from bio object +--- @tparam[opt=256] number max line len +--- @treturn string string length may be less than param len +-function gets() end +- +---- write data to bio object +--- @tparam string data +--- @treturn number length success write +-function write() end +- +---- put line to bio object +--- @tparam string data +--- @treturn number length success write +-function puts() end +- +---- get mem data, only support mem bio object +--- @treturn string +-function get_mem() end +- +---- push bio append to chain of bio, if want to free a chain use free_all() +--- @tparam bio append +--- @treturn bio +-function push() end +- +---- remove bio from chain +--- @tparam bio toremove +-function pop() end +- +---- free a chain +-function free_all() end +- +---- close bio +-function close() end +- +---- get type of bio +--- @treturn string +-function type() end +- +--- reset bio +--- @TODO string +-function reset() end +- +-end --define class +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/cipher.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/cipher.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/cipher.lua 2019-02-13 11:31:40.283968667 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/cipher.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,229 +0,0 @@ +---- +--- Provide cipher function in lua. +--- +--- @module cipher +--- @usage +--- cipher = require('openssl').cipher +--- +- +-do -- define module function +- +---- list all support cipher algs +--- +--- @tparam[opt] boolean alias include alias names for cipher alg, default true +--- @treturn[table] all cipher methods +--- +-function list() end +- +- +---- get evp_cipher object +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @treturn evp_cipher cipher object mapping EVP_MD in openssl +--- +--- @see evp_cipher +-function get() end +- +---- get evp_cipher_ctx object for encrypt or decrypt +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam boolean encrypt true for encrypt,false for decrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn evp_cipher_ctx cipher object mapping EVP_CIPHER_CTX in openssl +--- +--- @see evp_cipher_ctx +-function new() end +- +---- get evp_cipher_ctx object for encrypt +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn evp_cipher_ctx cipher object mapping EVP_CIPHER_CTX in openssl +--- +--- @see evp_cipher_ctx +-function encrypt_new() end +- +---- get evp_cipher_ctx object for decrypt +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn evp_cipher_ctx cipher object mapping EVP_CIPHER_CTX in openssl +--- +--- @see evp_cipher_ctx +-function decrypt_new() end +- +---- quick encrypt or decrypt +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam boolean encrypt true for encrypt,false for decrypt +--- @tparam string input data to encrypt or decrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn string result +-function cipher() end +- +---- quick encrypt or decrypt,alias to cipher +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam boolean encrypt true for encrypt,false for decrypt +--- @tparam string input data to encrypt or decrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn string result +-function openssl.cipher() end +- +---- quick encrypt +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam string input data to encrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn string result encrypt data +-function encrypt() end +- +---- quick decrypt +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam string input data to decrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn string result decrypt data +-function decrypt() end +- +-end +- +-do -- define class +- +---- openssl.evp_cipher object +--- @type evp_cipher +--- +-do -- define evp_cipher +- +- +---- get infomation of evp_cipher object +--- +--- @treturn table info keys include name,block_size,key_length,iv_length,flags,mode +-function info() end +- +---- derive key +--- +--- @tparam string data derive data +--- @tparam string[opt] string salt salt will get strong security +--- @tparam ev_digest|string md digest method used to diver key, default with 'sha1' +--- @treturn string key +--- @treturn string iv +-function BytesToKey() end +- +---- do encrypt or decrypt +--- +--- @tparam boolean encrypt true for encrypt,false for decrypt +--- @tparam string input data to encrypt or decrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn string result +-function cipher() end +- +---- do encrypt +--- +--- @tparam string input data to encrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn string result +-function encrypt() end +- +---- do decrypt +--- +--- @tparam string input data to decrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn string result +-function decrypt() end +- +---- get evp_cipher_ctx to encrypt or decrypt +--- +--- @tparam boolean encrypt true for encrypt,false for decrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn evp_cipher_ctx evp_cipher_ctx object +--- +--- @see evp_cipher_ctx +-function new() end +- +---- get evp_cipher_ctx to encrypt +--- +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn evp_cipher_ctx evp_cipher_ctx object +--- +--- @see evp_cipher_ctx +-function encrypt_new() end +- +---- get evp_cipher_ctx to decrypt +--- +--- @tparam boolean encrypt true for encrypt,false for decrypt +--- @tparam string key secret key +--- @tparam[opt] string iv +--- @tparam[opt] boolean pad true for padding default +--- @tparam[opt] engine engine custom crypto engine +--- @treturn evp_cipher_ctx evp_cipher_ctx object +--- +--- @see evp_cipher_ctx +-function decrypt_new() end +- +-end +- +-do -- define evp_cipher_ctx +- +---- openssl.evp_cipher_ctx object +--- @type evp_cipher_ctx +--- +- +---- get infomation of evp_cipher_ctx object +--- +--- @treturn table info keys include block_size,key_length,iv_length,flags,mode,nid,type, evp_cipher +-function info() end +- +---- feed data to do cipher +--- +--- @tparam string msg data +--- @treturn string result parture result +-function update() end +- +---- get result of cipher +--- +--- @treturn string result last result +-function final() end +- +-end +- +-end +- +- +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/cms.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/cms.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/cms.lua 2019-02-13 11:31:40.283968667 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/cms.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,142 +0,0 @@ +---- Provide cms function in lua. +--- cms are based on apps/cms.c from the OpenSSL dist, so for more information, see the documentation for OpenSSL. +--- cms api need flags, not support "detached", "nodetached", "text", "nointern", "noverify", "nochain", "nocerts", +--- "noattr", "binary", "nosigs" +--- +--- Decrypts the S/MIME message in the BIO object and output the results to BIO object. +--- recipcert is a CERT for one of the recipients. recipkey specifies the private key matching recipcert. +--- Headers is an array of headers to prepend to the message, they will not be included in the encoded section. +--- +--- @module cms +--- @usage +--- cms = require('openssl').cms +--- +- +-do -- define module function +- +---- create cms object +--- @treturn cms +-function create() end +- +---- read cms object +--- @tparam bio input +--- @tparam[opt=0] number flags +--- @treturn cms +-function create() end +- +---- create digest cms object +--- @tparam bio input +--- @tparam evp_digest|string md_alg +--- @tparam[opt=0] number flags +--- @treturn cms +-function create() end +- +---- encrypt with recipt certs +--- @tparam stack_of_x509 recipt certs +--- @tparam bio input +--- @tparam string|evp_cipher cipher_alg +--- @tparam[opt=0] number flags +--- @tparam[opt=nil] table options, may have key,keyid, password field which must be string type +--- @treturn cms +-function encrypt() end +- +---- decrypt cms message +--- @tparam cms message +--- @tparam evp_pkey pkey +--- @tparam x509 recipt +--- @tparam bio dcount output object +--- @tparam bio out output object +--- @tparam[opt=0] number flags +--- @tparam[opt=nil] table options may have key, keyid, password field, which must be string type +--- @treturn boolean +-function decrypt() end +- +---- make signed cms object +--- @tparam x509 signer cert +--- @tparam evp_pkey pkey +--- @tparam stack_of_x509 certs include in the CMS +--- @tparam bio input_data +--- @tparam[opt=0] number flags +--- @treturn cms object +-function sign() end +- +---- verfiy signed cms object +--- @tparam cms signed +--- @tparam string verify_mode, must be 'verify' +--- @tparam stack_of_x509 others +--- @tparam x509_store castore +--- @tparam bio message +--- @tparam bio out +--- @tparam[opt=0] number flags +--- @treturn boolean result +-function verify() end +- +---- verify digest cms object +--- @tparam cms digested +--- @tparam string verify_mode, must be 'digest' +--- @tparam bio input message +--- @tparam bio out content +--- @tparam[opt=0] number flags +--- @treturn boolean result +-function verify() end +- +---- verify receipt cms object +--- @tparam cms cms +--- @tparam string verify_mode must be 'receipt' +--- @tparam cms source +--- @tparam stack_of_x509 certs +--- @tparam x509_store store +--- @tparam[opt=0] number flags +--- @treturn boolean result +-function verify() end +- +---- read cms object from input bio or string +--- @tparam bio|string input +--- @tparam[opt='auto'] string format, support 'auto','smime','der','pem' +--- auto will only try 'der' or 'pem' +--- @tparam[opt=nil] bio content, only used when format is 'smime' +--- @treturn cms +-function read() end +- +---- write cms object to bio object +--- @tparam cms cms +--- @tparam bio out +--- @tparam bio in +--- @tparam[opt=0] number flags +--- @tparam[opt='smime'] string format +--- @treturn boolean +-function write() end +- +---- create compress cms object +--- @tparam bio input +--- @tparam string alg, zlib or rle +--- @tparam[opt=0] number flags +--- @treturn cms +-function compress() end +- +---- uncompress cms object +--- @tparam cms cms +--- @tparam bio input +--- @tparam bio out +--- @tparam[opt=0] number flags +--- @treturn boolean +-function uncompress() end +- +---- create enryptdata cms +--- @tparam bio input +--- @tparam cipher|string cipher_alg +--- @tparam strig key +--- @tparam[opt=0] number flags +--- @treturn cms object +-function EncryptedData_encrypt() end +- +---- decrypt encryptdata cms +--- @tparam cms encrypted +--- @tparam string key +--- @tparam bio out +--- @tparam[opt=0] number flags +--- @treturn boolean result +-function EncryptedData_decrypt() end +- +-end +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/config.ld luvi-src-v2.7.6/deps/lua-openssl/ldoc/config.ld +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/config.ld 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/config.ld 1970-01-01 01:00:00.000000000 +0100 +@@ -1,33 +0,0 @@ +-project='lua-openssl' +-title='lua-openssl Docmentation' +-description='Openssl binding for Lua' +-format='discount' +-backtick_references=false +-file={ +- 'openssl.lua', +- 'asn1.lua', +- 'bio.lua', +- 'cipher.lua', +- 'digest.lua', +- 'hmac.lua', +- 'pkey.lua', +- 'x509.lua', +- 'x509_name.lua', +- 'x509_extension.lua', +- 'x509_attr.lua', +- 'x509_req.lua', +- 'x509_crl.lua', +- 'x509_store.lua', +- 'pkcs7.lua', +- 'cms.lua', +- 'pkcs12.lua', +- 'timestamp.lua', +- 'ssl.lua', +- 'sk.lua' +-} +-dir='doc' +-readme='README.md' +-style='!pale' +-kind_names={topic='Manual',script='Programs'} +-examples = { +-} +\ No newline at end of file +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/digest.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/digest.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/digest.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/digest.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,156 +0,0 @@ +---- +--- Provide digest function in lua. +--- +--- @module digest +--- @usage +--- digest = require('openssl').digest +--- +- +-do -- define module function +- +---- list all support digest algs +--- +--- @tparam[opt] boolean alias include alias names for digest alg, default true +--- @treturn[table] all methods +--- +-function list() end +- +---- get evp_digest object +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @treturn evp_digest digest object mapping EVP_MD in openssl +--- +--- @see evp_digest +-function get() end +- +---- get evp_digest_ctx object +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @treturn evp_digest_ctx digest object mapping EVP_MD_CTX in openssl +--- +--- @see evp_digest_ctx +-function new() end +- +---- quick method to generate digest result +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam string msg to compute digest +--- @tparam[opt] boolean raw binary result return if set true, or hex encoded string default +--- @treturn string digest result value +-function digest() end +- +---- create digest object for sign +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam[opt=nil] engine object +--- @treturn evp_digest_ctx +-function signInit() end +- +---- create digest object for verify +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam[opt=nil] engine object +--- @treturn evp_digest_ctx +-function verifyInit() end +- +-end +- +-do -- define class +- +---- openssl.evp_digest object +--- @type evp_digest +--- +-do -- define evp_digest +- +---- create new evp_digest_ctx +--- +--- @tparam[opt] engine, nothing will use default engine +--- @treturn evp_digest_ctx ctx +--- @see evp_digest_ctx +-function new() end +- +---- get infomation of evp_digest object +--- +--- @treturn table info keys include nid,name size,block_size,pkey_type,flags +-function info() end +- +---- compute msg digest result +--- +--- @tparam string msg data to digest +--- @tparam[opt] engine, eng +--- @treturn string result a binary hash value for msg +-function digest() end +- +---- create digest object for sign +--- +--- @tparam[opt=nil] engine object +--- @treturn evp_digest_ctx +-function signInit() end +- +---- create digest object for verify +--- +--- @tparam[opt=nil] engine object +--- @treturn evp_digest_ctx +-function verifyInit() end +- +-end +- +-do -- define evp_digest_ctx +- +---- openssl.evp_digest_ctx object +--- @type evp_digest_ctx +--- +- +---- get infomation of evp_digest_ctx object +--- +--- @treturn table info keys include size,block_size,digest +-function info() end +- +---- feed data to do digest +--- +--- @tparam string msg data +--- @treturn boolean result true for success +-function update() end +- +---- get result of digest +--- +--- @tparam[opt] string last last part of data +--- @tparam[opt] boolean raw binary or hex encoded result, default true for binary result +--- @treturn string val hash result +-function final() end +- +- +---- reset evp_diget_ctx to reuse +--- +-function reset() end +- +---- feed data for sign to get signature +--- +--- @tparam string data to be signed +--- @treturn boolean result +-function signUpdate() end +- +---- feed data for verify with signature +--- +--- @tparam string data to be verified +--- @treturn boolean result +-function verifyUpdate() end +- +---- get result of sign +--- +--- @tparam evp_pkey private key to do sign +--- @treturn string singed result +-function signFinal() end +- +---- get verify result +--- +--- @tparam string signature +--- @treturn boolean result, true for verify pass +-function verifyFinal() end +- +-end +- +-end +- +- +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/hmac.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/hmac.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/hmac.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/hmac.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,77 +0,0 @@ +---- +--- Provide hmac function in lua. +--- +--- @module hmac +--- @usage +--- hamc = require('openssl').hmac +--- +- +-do -- define module function +- +---- compute hmac one step, in module openssl +--- +--- @tparam evp_digest|string|nid digest digest alg identity +--- @tparam string key +--- @tparam[opt] engine engine, nothing with default engine +--- @treturn string result binary string +--- +-function openssl.hmac() end +- +---- compute hmac one step, in module openssl.hamc +--- +--- @tparam evp_digest|string|nid digest digest alg identity +--- @tparam string key +--- @tparam boolean raw, return binary or hex encoded string, true false binary or hex +--- @tparam[opt] engine engine, nothing with default engine +--- @treturn string result binary or hex string +-function hmac() end +- +---- alias for hmac +--- +--- @tparam evp_digest|string|nid digest digest alg identity +--- @tparam string key +--- @tparam boolean raw, return binary or hex encoded string, true false binary or hex +--- @tparam[opt] engine engine, nothing with default engine +--- @treturn string result binary or hex string +-function digest() end +- +---- get hamc_ctx object +--- +--- @tparam string|integer|asn1_object alg name, nid or object identity +--- @tparam string key secret key +--- @tparam[opt] engine engine, nothing with default engine +--- @treturn hamc_ctx hmac object mapping HMAC_CTX in openssl +--- +--- @see hmac_ctx +-function new() end +- +-end +- +-do -- define class +- +---- openssl.hmac_ctx object +--- @type hmac_ctx +--- +- +-do -- define hmac_ctx +- +---- feed data to do digest +--- +--- @tparam string msg data +-function update() end +- +---- get result of hmac +--- +--- @tparam[opt] string last last part of data +--- @tparam[opt] boolean raw binary or hex encoded result, default true for binary result +--- @treturn string val hash result +-function final() end +- +- +---- reset hmac_ctx to reuse +--- +-function reset() end +- +-end +- +-end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/openssl.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/openssl.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/openssl.lua 2019-02-13 11:31:40.283968667 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/openssl.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,76 +0,0 @@ +---- +--- Provide openssl base function in lua. +--- +--- @module openssl +--- @usage +--- openssl = require('openssl') +--- +- +-do -- define module function +- +--- Most lua-openssl function or methods return nil or false when error or +--- failed, followed by string type error _reason_ and number type error _code_, +--- _code_ can pass to openssl.error() to get more error information. +- +---- hex encode or decode string +--- @tparam string str +--- @tparam[opt=true] boolean encode true to encoed, false to decode +--- @treturn string +-function hex() end +- +---- base64 encode or decode +--- @tparam string|bio input +--- @tparam[opt=true] boolean encode true to encoed, false to decode +--- @tparam[opt=true] boolean NO_NL true with newline, false without newline +--- @treturn string +-function base64() end +- +---- get method names +--- @tparam string type support 'cipher','digests','pkeys','comps' +--- @treturn table as array +-function list() end +- +---- get last or given error infomation +--- @tparam[opt] number error, default use ERR_get_error() return value +--- @tparam[opt=false] boolean clear the current thread's error queue. +--- @treturn number errcode +--- @treturn string reason +--- @treturn string library name +--- @treturn string function name +--- @treturn boolean is this is fatal error +-function error() end +- +---- get random bytes +--- @tparam number length +--- @tparam[opt=false] boolean strong true to generate strong randome bytes +--- @treturn string +-function random() end +- +---- get random generator state +--- @tparam boolean result true for sucess +-function rand_status() end +- +---- load rand seed from file +--- @tparam[opt=nil] string file path to laod seed, default opensl management +--- @treturn boolean result +-function rand_load() end +- +---- save rand seed to file +--- @tparam[opt=nil] string file path to save seed, default openssl management +--- @treturn bool result +-function rand_write() end +- +---- cleanup random genrator +-function rand_cleanup() end +- +---- get openssl engine object +--- @tparam string engine_id +--- @treturn engine +-function engine() end +- +--- get lua-openssl version +--- @tparam[opt] boolean format result will be number when set true, or string +--- @treturn lua-openssl version, lua version, openssl version +-function version() end +- +-end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/pkcs12.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/pkcs12.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/pkcs12.lua 2019-02-13 11:31:40.283968667 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/pkcs12.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,28 +0,0 @@ +---- +--- Provide pkcs12 function in lua. +--- +--- @module pkcs12 +--- @usage +--- pkcs12 = require('openssl').pkcs12 +--- +- +-do -- define module function +- +---- parse pkcs12 data as lua table +--- +--- @tparam string|bio input pkcs12 content +--- @tparam string password for pkcs12 +--- @treturn table result contain 'cert', 'pkey', 'extracerts' keys +-function read() end +- +---- create and export pkcs12 data +--- @tparam x509 cert +--- @tparam evp_pkey pkey +--- @tparam string password +--- @tparam[opt] string friendlyname +--- @tparam[opt] table|stak_of_x509 extracerts +--- @treturn string data +-function export() end +- +-end +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/pkcs7.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/pkcs7.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/pkcs7.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/pkcs7.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,91 +0,0 @@ +---- +--- Provide pkcs7 function in lua. +--- +--- @module pkcs7 +--- @usage +--- pkcs7 = require('openssl').pkcs7 +--- +- +-do -- define module function +- +---- read pkcs7 +--- read string or bio object, which include pkcs7 content +--- @tparam bio|string input +--- @tparam[opt='auto'] format allow 'auto','der','pem','smime' +--- auto will only try 'der' or 'pem' +--- @tparam string password for pkcs12 +--- @treturn pkcs7 object or nil +--- @treturn string content exist only smime format +-function read() end +- +---- sign message with signcert and signpkey to create pkcs7 object +--- @tparam string|bio msg +--- @tparam x509 sigcert +--- @tparam evp_pkey signkey +--- @tparam[opt] stack_of_x509 cacerts +--- @tparam[opt=0] number flags +--- @treturn pkcs7 object +-function sign() end +- +---- verify pkcs7 object, and return msg content, follow by singers +--- @tparam pkcs7 in +--- @tparam[opt] stack_of_x509 signercerts +--- @tparam[opt] x509_store cacerts +--- @tparam[opt] string|bio msg +--- @tparam[opt=0] number flags +--- @treturn[1] string content +--- @treturn[1] boolean result +-function verify() end +- +---- encrypt message with recipcerts certificates return encrypted pkcs7 object +--- @tparam string|bio msg +--- @tparam stack_of_x509 recipcerts +--- @tparam[opt='rc4'] string|evp_cipher cipher +--- @tparam[opt] number flags +-function encrypt() end +- +---- decrypt encrypted pkcs7 message +--- @tparam pkcs7 input +--- @tparam x509 recipcert +--- @tparam evp_pkey recipkey +--- @treturn string decrypt message +-function decrypt() end +- +-end +- +- +-do -- define class +- +---- openssl.pkcs7 object +--- @type pkcs7 +--- +- +-do -- define pkcs7 +- +---- export pkcs7 as string +--- @tparam[opt=true] boolean pem default export as pem format, false export as der string +--- @treturn string +-function export() end +- +---- export pkcs7 as a string +--- @treturn table a table has pkcs7 infomation, include type,and other things relate to types +-function parse() end +- +---- verify pkcs7 object, and return msg content, follow by singers +--- @tparam[opt] stack_of_x509 signercerts +--- @tparam[opt] x509_store cacerts +--- @tparam[opt] string|bio msg +--- @tparam[opt=0] number flags +--- @treturn string content +--- @treturn stack_of_x509 signers +-function verify() end +- +---- decrypt encrypted pkcs7 message +--- @tparam x509 recipcert +--- @tparam evp_pkey recipkey +--- @treturn string decrypt message +-function decrypt() end +- +-end +- +-end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/pkey.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/pkey.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/pkey.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/pkey.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,201 +0,0 @@ +------------- +--- Provide Public/Private key module. +--- @module pkey +--- @usage +--- pkey = require'openssl'.pkey +- +-do --define module function +- +---- generate a new ec keypair +--- @tparam string alg, alg must be 'ec' +--- @tparam string|number curvename this can be integer as curvename NID +--- @tparam[opt] integer flags when alg is ec need this. +--- @treturn evp_pkey object with mapping to EVP_PKEY in openssl +-function new() end +- +---- generate a new keypair +--- @tparam[opt='rsa'] string alg, accept 'rsa','dsa','dh' +--- @tparam[opt=1024|512] integer bits, rsa with 1024,dh with 512 +--- @tparam[opt] when alg is rsa give e value default is 0x10001 +--- @treturn evp_pkey object with mapping to EVP_PKEY in openssl +-function new() end +- +---- create a new keypair by factors of keypair or get public key only +--- @tparam table factors to create private/public key, key alg only accept accept 'rsa','dsa','dh','ec' and must exist
+--- when arg is rsa, table may with key n,e,d,p,q,dmp1,dmq1,iqmp, both are binary string or openssl.bn
+--- when arg is dsa, table may with key p,q,g,priv_key,pub_key, both are binary string or openssl.bn
+--- when arg is dh, table may with key p,g,priv_key,pub_key, both are binary string or openssl.bn
+--- when arg is ec, table may with D,X,Y,Z,both are binary string or openssl.bn
+--- @treturn evp_pkey object with mapping to EVP_PKEY in openssl +--- @usage +--- --create rsa public key +--- pubkey = new({alg='rsa',n=...,e=...} +--- --create new rsa +--- rsa = new({alg='rsa',n=...,q=...,e=...,...} +-function new() end +- +---- get public key from private key object +--- @tparam evp_pkey priv_key +--- @treturn evp_pkey pub_key +--- @see evp_pkey +-function get_public() end +- +---- read public/private key from data +--- @tparam string|openssl.bio input string data or bio object +--- @tparam[opt=false] boolean priv prikey set true when input is private key +--- @tparam[opt='auto'] format format or encoding of input, support 'auto','pem','der' +--- @tparam[opt] string passhprase when input is private key, or key types 'ec','rsa','dsa','dh' +--- @treturn evp_pkey public key +--- @see evp_pkey +-function read() end +- +---- sign message with private key +--- @tparam evp_pkey key key used to sign message +--- @tparam string data data be signed +--- @tparam[opt='SHA1'] string|env_digest md_alg default use sha-1 +--- @treturn string signed message +-function sign() end +- +---- verify signed message with public key +--- @tparam evp_pkey key key used to verify message +--- @tparam string data data be signed +--- @tparam string signature signed result +--- @tparam[opt='SHA1'] string|env_digest md_alg default use sha-1 +--- @tparam boolean true for pass verify +-function verify() end +- +---- encrypt message with public key +--- encrypt length of message must not longer than key size, if shorter will do padding,currently supports 6 padding modes. +--- They are: pkcs1, sslv23, no, oaep, x931, pss. +--- @tparam evp_pkey key key used to encrypted message +--- @tparam string data data to be encrypted +--- @tparam string[opt='pkcs1'] string padding padding mode +--- @treturn string encrypted message +-function encrypt() end +- +---- decrypt message with private key +--- pair with encrypt +--- @tparam evp_pkey key key used to decrypted message +--- @tparam string data data to be decrypted +--- @tparam string[opt='pkcs1'] string padding padding mode +--- @treturn[1] string result +--- @treturn[2] nil +-function decrypt() end +- +---- seal and encrypt message with one public key +--- data be encrypt with secret key, secret key be encrypt with public key +--- encrypts data using pubkeys in table, so that only owners of the respective private keys and ekeys can decrypt and read the data. +--- @tparam table pubkeys public keys to encrypt secret key +--- @tparam string data data to be encrypted +--- @tparam[opt='RC4'] cipher|string alg +--- @treturn string data encrypted +--- @treturn table ekey secret key encrypted by public key +--- @treturn stringiv +-function seal() end +- +---- seal and encrypt message with one public key +--- data be encrypt with secret key, secret key be encrypt with public key +--- @tparam evp_pkey pubkey public keys to encrypt secret key +--- @tparam string data data to be encrypted +--- @tparam[opt='RC4'] cipher|string alg +--- @treturn string data encrypted +--- @treturn string skey secret key encrypted by public key +--- @treturn string iv +-function seal() end +- +---- open and ecrypted seal data with private key +--- @tparam evp_pkey pkey private key used to open encrypted secret key +--- @tparam string ekey encrypted secret key +--- @tparam string string iv +--- @tparam[opt='RC4'] evp_cipher|string md_alg +--- @treturn string data decrypted message or nil on failure +-function open() end +- +-end -- define module +- +- +-do -- define class +- +---- openssl.evp_pkey object +--- @type evp_pkey +--- +- +-do -- define evp_pkey +- +---- export evp_pkey as pem string +--- @tparam[opt=true] boolean pem default export as pem format, false export as der string +--- @tparam[opt=false] boolean raw_key true for export low layer key just rsa,dsa,ec, and public key only support RSA +--- @tparam[opt] string passphrase if given, export key will encrypt with des-cbc-ede, +--- only need when export private key +--- @treturn string +-function export() end +- +---- export evp_pkey as der string +--- @tparam boolean pem set false to export as der string +--- @tparam[opt=false] boolean raw_key true for export low layer key just rsa,dsa,ec, and public key only support RSA +--- @tparam[opt] string passphrase if given, export key will encrypt with des-cbc-ede, +--- only need when export private key +--- @treturn string +-function export() end +- +---- get key details as table +--- @treturn table infos with key bits,pkey,type, pkey may be rsa,dh,dsa, show as table with factor hex encoded bignum +-function parse() end +- +---- return key is private or public +--- @treturn boolean ture is private or public key +-function is_private() end +- +---- compute dh key, check whether then supplied key is a private key +--- by checking then prime factors whether set +--- @tparam string remote_public_key +--- @treturn string +--- @todo: more check +-function compute_key() end +- +---- sign message with private key +--- @tparam string data data be signed +--- @tparam[opt='SHA1'] string|env_digest md_alg default use sha-1 +--- @treturn string signed message +-function sign() end +- +---- verify signed message with public key +--- @tparam string data data be signed +--- @tparam string signature signed result +--- @tparam[opt='SHA1'] string|env_digest md_alg default use sha-1 +--- @treturn boolean true for pass verify +-function verify() end +- +---- encrypt message with public key +--- encrypt length of message must not longer than key size, if shorter will do padding,currently supports 6 padding modes. +--- They are: pkcs1, sslv23, no, oaep, x931, pss. +--- @tparam string data data to be encrypted +--- @tparam string[opt='pkcs1'] string padding padding mode +--- @treturn string encrypted message +-function encrypt() end +- +---- decrypt message with private key +--- pair with encrypt +--- @tparam string data data to be decrypted +--- @tparam string[opt='pkcs1'] string padding padding mode +--- @treturn[1] string result +--- @treturn[2] nil +-function decrypt() end +- +---- seal and encrypt message with one public key +--- data be encrypt with secret key, secret key be encrypt with public key +--- @tparam string data data to be encrypted +--- @tparam[opt='RC4'] cipher|string alg +--- @treturn string data encrypted +--- @treturn string skey secret key encrypted by public key +--- @treturn string iv +-function seal() end +- +---- open and ecrypted seal data with private key +--- @tparam string ekey encrypted secret key +--- @tparam string string iv +--- @tparam[opt='RC4'] evp_cipher|string md_alg +--- @treturn string data decrypted message or nil on failure +-function open() end +- +-end --define class +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/sk.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/sk.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/sk.lua 2019-02-13 11:31:40.283968667 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/sk.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,74 +0,0 @@ +---- +--- Provide hmac function in lua. +- +--- +--- @module hmac +--- @usage +--- hamc = require('openssl').hmac +--- +- +-do -- define module function +- +---- read stack_of_x509 from string data or bio input +--- @tparam string|bio input +--- @treturn stack_of_x509 +--- @see stack_of_object +-function openssl.sk_x509_read() end +- +---- contrust stack_of_x509 from table +--- @tparam table certs x509 object certs +--- @treturn stack_of_x509 +--- @see stack_of_object +-function openssl.sk_x509_new() end +- +-end +- +-do -- define class +- +---- openssl.stack_of_object object +--- stack_of_x509_extension, stack_of_x509, stack_of_x509_attribute object has same interface. +--- stack_of_x509 is an important object in lua-openssl, it can be used as a certchain, trusted CA files or unstrust certs. +--- object not support x509, x509_extension or x509_attribute +--- @type stack_of_object +--- +- +-do -- define stack_of_object +- +---- push an object into stack +--- @tparam object obj +--- @treturn stack_of_object self +-function push() end +- +---- pop an object from stack +--- @treturn object +-function pop() end +- +---- set object at given location +--- @tparam integer location +--- @tparam object object +--- @treturn stack_of_object self +-function set() end +- +---- get object at given location +--- @tparam integer location +--- @treturn object obj +-function get() end +- +---- insert object at given location +--- @tparam object obj +--- @tparam integer location +--- @treturn stack_of_x509 self +-function insert() end +- +---- delete object at geiven location +--- @tparam integer location +--- @treturn object deleted object +-function delete() end +- +---- convert stack_of_object to table +--- @@treturn table contain object index start from 1 +-function totable() end +- +-end +- +-end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/ssl.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/ssl.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/ssl.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/ssl.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,408 +0,0 @@ +---- +--- Provide ssl function in lua. +--- +--- @module ssl +--- @usage +--- hamc = require('openssl').ssl +--- +- +-do -- define module function +- +---- create ssl_ctx object, which mapping to SSL_CTX in openssl. +--- @tparam string protocol support 'SSLv3', 'SSLv23', 'SSLv2', 'TSLv1', 'TSLv1_1','TSLv1_2','DTLSv1', and can be follow by '_server' or '_client' +--- @tparam[opt] string support_ciphers, if not given, default of openssl will be used +--- @treturn ssl_ctx +-function ctx_new() end +- +---- get alert_string for ssl state +--- @tparam number alert +--- @tparam[opt=false] boolean long +--- @treturn string alert type +--- @treturn string desc string, if long set true will return long info +-function alert_string() end +- +-end +- +-do -- define class +- +---- openssl.ssl_ctx object +--- @type ssl_ctx +--- +- +-do -- define ssl_ctx +- +---- tell ssl_ctx use private key and certificate, and check private key +--- @tparam evp_pkey pkey +--- @tparam x509 cert +--- @treturn boolean result return true for ok, or nil followed by errmsg and errval +-function use() end +- +---- add client ca cert and option extra chain cert +--- @tparam x509 clientca +--- @tparam[opt] table extra_chain_cert_array +--- @treturn boolean result +-function add() end +- +---- set temp callback +--- @tparam string keytype, 'dh','ecdh',or 'rsa' +--- @tparam function tmp_cb +--- @param[opt] vararg +-function set_tmp() end +- +---- set tmp key content pem format +--- @tparam string keytype, 'dh','ecdh',or 'rsa' +--- @tparam string key_pem +-function set_tmp() end +- +---- set ecdh with given curvename as tmp key +--- @tparam string keytype, must be 'ecdh' +--- @tparam string curvename +-function set_tmp() emd +- +---- clean given mode +--- mode support 'enable_partial_write','accept_moving_write_buffer','auto_retry','no_auto_chain','release_buffers' +--- @tparam boolean clear must be true +--- @tparam string mode +--- @param[opt] ... +--- @treturn string +--- @treturn ... +--- @usage +--- modes = { ssl_ctx:mode('enable_partial_write','accept_moving_write_buffer','auto_retry') }, +--- +--- for i, v in ipairs(modes) +--- print(v) +--- end +--- --output 'enable_partial_write','accept_moving_write_buffer','auto_retry' +-function mode() end +- +---- get options +--- @treturn table string list of current options +-function options() end +- +---- set options +--- @tparam string option, support "microsoft_sess_id_bug", "netscape_challenge_bug", "netscape_reuse_cipher_change_bug", +--- "sslref2_reuse_cert_type_bug", "microsoft_big_sslv3_buffer", "msie_sslv3_rsa_padding","ssleay_080_client_dh_bug", +--- "tls_d5_bug","tls_block_padding_bug","dont_insert_empty_fragments","all", please to see ssl_options.h +--- @treturn table string list of current options after set new option +-function options() end +- +---- clear options +--- @tparam boolean clear set true to clear options +--- @tparam string option, support "microsoft_sess_id_bug", "netscape_challenge_bug", "netscape_reuse_cipher_change_bug", +--- "sslref2_reuse_cert_type_bug", "microsoft_big_sslv3_buffer", "msie_sslv3_rsa_padding","ssleay_080_client_dh_bug", +--- "tls_d5_bug","tls_block_padding_bug","dont_insert_empty_fragments","all", please to see ssl_options.h +--- @treturn table string list of current options after clear some option +-function options() end +- +---- get timeout +--- @return number +-function timeout() end +- +---- set timeout +--- @tparam number timeout +--- @treturn number previous timeout +-function timeout() end +- +---- get quit_shutdown is set or not +--- Normally when a SSL connection is finished, the parties must send out +--- "close notify" alert messages using ***SSL:shutdown"*** for a clean shutdown. +--- @treturn boolean result +-function quiet_shutdown() end +- +---- set quiet_shutdown +--- @tparam boolean quiet +--- When setting the "quiet shutdown" flag to 1, ***SSL:shutdown*** will set the internal flags +--- to SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN. ***SSL:shutdown*** then behaves like +--- ***SSL:set_shutdown*** called with SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN. +--- The session is thus considered to be shutdown, but no "close notify" alert +--- is sent to the peer. This behaviour violates the TLS standard. +--- The default is normal shutdown behaviour as described by the TLS standard. +--- @treturn boolean result +-function quiet_shutdown() end +- +---- set verify locations with cafile and capath +--- ssl_ctx:verify_locations specifies the locations for *ctx*, at +--- which CA certificates for verification purposes are located. The certificates +--- available via *CAfile* and *CApath* are trusted. +--- @tparam string cafile +--- @tparam string capath +--- @treturn boolean result +-function verify_locations() end +- +---- get certificate verification store of ssl_ctx +---@treturn x509_store store +-function cert_store() end +- +---- set or replaces then certificate verification store of ssl_ctx +--- @tparam x509_store store +---@treturn x509_store store +-function cert_store() end +- +---- get verify depth when cert chain veirition +--- @treturn number depth +-function verify_depth() end +- +---- set verify depth when cert chain veirition +--- @tparam number depth +--- @treturn number depth +-function verify_depth() end +- +---- get verify_mode, return number mode and all string modes list +--- @treturn number mode_code +--- @return ... +- -- none: not verify client cert +- -- peer: verify client cert +- -- fail: if client not have cert, will failure +- -- once: verify client only once. +--- @usage +--- mode = {ctx:verify_mode()} +--- print('integer mode',mode[1]) +--- for i=2, #mode then +--- print('string mode:'..mode[i]) +--- end +-function verify_mode() end +- +---- set ssl verify mode and callback +--- @tparam number mode, mode set to ctx, must be ssl.none or ssl.peer, and ssl.peer support combine with ssl.fail or ssl.once +--- @tparam[opt=nil] function ssl verify callback in lua function, not give will use default openssl callback, when mode is 'none', will be ignore this +--- verify_cb must be boolean function(verifyarg) prototype, return true to continue or false to end ssl handshake +--- verifyarg has field 'error', 'error_string','error_depth','current_cert', and 'preverify_ok' +--- @treturn boolean result +-function verify_mode() end +- +---- set certificate verify callback function +--- @tparam[opt] function cert_verify_cb with boolean function(verifyargs) prototype, if nil or none will use openssl default callback +--- verifyargs has field 'error', 'error_string','error_depth','current_cert' +-function set_cert_verify() end +- +---- set certificate verify options +--- @tparam table verify_cb_flag support field always_continue with boolean value and verify_depth with number value. +-function set_cert_verify() end +- +---- get current session cache mode +--- @ table modes as array, mode is 'no_auto_clear','server','client','both','off' +-function session_cache_mode() +- +---- set session cache mode,and return old mode +--- @param mode string support 'no_auto_clear','server','client','both','off', +--- 'no_auto_clear' can be combine with others, so accept one or two param. +-function session_cache_mode(...) +- +---- create bio object +--- @tparam string host_addr format like 'host:port' +--- @tparam[opt=false] boolean server, true listen at host_addr,false connect to host_addr +--- @tparam[opt=true] boolean autoretry ssl operation autoretry mode +--- @treturn bio bio object +-function bio() end +- +---- create ssl object +--- @tparam bio bio +--- @tparam[opt=false] boolean server, true will make ssl server +--- @treturn ssl +-function ssl() end +- +---- create ssl object +--- @tparam bio input +--- @tparam bio ouput +--- @tparam[opt=false] boolean server, true will make ssl server +--- @treturn ssl +-function ssl() end +- +-end +- +-do --define ssl object +- +---- openssl.ssl object +--- All SSL object IO operation methods(connect, accept, handshake, read, +--- peek or write) return nil or false when fail or error. +--- When nil returned, it followed by 'ssl' or 'syscall', means SSL layer or +--- system layer error. When false returned, it followed by number 0, +--- 'want_read','want_write','want_x509_lookup','want_connect','want_accept'. +--- Numnber 0 means SSL connection closed, others means you should do some +--- SSL operation. +--- @type ssl +- +---- get value according to what, arg can be list, arg must be in below list +--- @tparam string arg +--- certificate: return SSL certificates +--- fd: return file or network connect fd +--- rfd: +--- wfd: +--- client_CA_list +--- read_ahead: -> boolean +--- shared_ciphers: string +--- cipher_list -> string +--- verify_mode: number +--- verify_depth +--- state_string +--- state_string_long +--- rstate_string +--- rstate_string_long +--- iversion +--- version +--- default_timeout, +--- certificates +--- verify_result +--- state +--- state_string +--- @return according to arg +-function get() end +- +---- set value according to what, arg can be list, arg must be in below list +--- @tparam string arg +--- certificate: return SSL certificates +--- fd: return file or network connect fd +--- rfd: +--- wfd: +--- client_CA: +--- read_ahead +--- cipher_list +--- verify_depth +--- purpose: +--- trust: +--- verify_result +--- state +--- @param value val type accroding to arg +--- @return value +-function set() end +- +---- tell ssl use private key and certificate, and check private key +--- @tparam evp_pkey pkey +--- @tparam[opt] x509 cert +--- @treturn boolean result return true for ok, or nil followed by errmsg and errval +-function use() end +- +---- get peer certificate and certificate chains +--- @treturn x509 certificate +--- @treturn sk_of_x509 chains of peer +-function peer() end +- +---- get socket fd of ssl +--- @treturn number fd +-function getfd() end +- +---- get current cipher info +--- @treturn table include name,version,id,bits,algbits and description +-function current_cipher() end +- +---- get current compression name +--- @treturn string +-function current_compression() end +- +---- get peer certificate verify result +--- @treturn boolean true for success +--- @treturn table all certificate in chains verify result +--- preverify_ok as boolean verify result +--- error as number error code +--- error_string as string error message +--- error_depth as number verify depth +--- current_cert as x509 certificate to verified +-function getpeerverification() end +- +---- get ssl session +--- @treturn ssl_session session object +-function session() end +- +---- set ssl session +--- @tparam string|ssl_session sesion +--- reuse session would speed up ssl handshake +--- @treturn boolean result +-function session() end +- +---- duplicate ssl object +--- @treturn ssl +-function dup() end +- +---- get ssl_ctx associate with current ssl +--- @treturn ssl_ctx +-function ctx() end +- +---- set ssl_ctx associate to current ssl +--- @tparam ssl_ctx ctx +--- @treturn ssl_ctx orgine ssl_ctx object +-function ctx() end +- +---- reset ssl object to allow another connection +--- @treturn boolean result true for success +-function clear() end +- +---- get want to do +--- @treturn string 'nothing', 'reading', 'writing', 'x509_lookup' +--- @treturn number state want +-function want() end +- +---- get number of bytes available inside SSL fro immediate read +--- treturn number +-function pending() end +- +---- do ssl server accept +--- @treturn boolean true for success +--- @treturn string fail reason +-function accept() end +- +---- do ssl client connect +--- @treturn boolean true for success +--- @treturn string fail reasion +-function connect() end +- +---- do ssl read +--- @tparam[opt=4096] number length to read +--- @treturn string data, nil or false for fail +--- @treturn string fail reason +-function read() end +- +---- do ssl peak, data can be read again +--- @tparam[opt=4096] number length to read +--- @treturn string data, nil or false for fail +--- @treturn string fail reason +-function peek() end +- +---- do ssl write +--- @tparam string data +--- @treturn number count of bytes write successfully +--- @treturn string fail reason +-function write() end +- +---- do ssl renegotiate +--- @treturn boolean true for success +--- @treturn string fail reasion +-function renegotiate() end +- +---- do ssl handshake, support both server and client side +--- @treturn boolean true for success +--- @treturn string fail reasion +-function handshake() end +- +---- shutdown SSL connection +-function shutdown() end +- +---- shutdown ssl connect with special mode, disable read or write, +--- enable or disable quite shutdown +--- @tparam string mode support 'read','write', 'quite', 'noquite' +-function shutdown() end +- +---- shutdown ssl connection with quite or noquite mode +--- @tparam boolean mode +--- @treturn[1] boolean if mode is true, return true or false for quite +--- @treturn[2] string if mode is false, return 'read' or 'write' for shutdown direction +-function shutdown() end +- +---- do ssl renegotiate_pending +--- @treturn boolean true for success +--- @treturn string fail reasion +-function renegotiate_pending() end +- +---- do ssl renegotiate_pending +--- @treturn boolean true for success +--- @treturn string fail reasion +-function renegotiate_pending() end +- +---- make ssl to client mode +-function set_connect_state() end +- +---- make ssl to server mode +-function set_accept_state() end +- +-end +- +-end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/timestamp.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/timestamp.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/timestamp.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/timestamp.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,334 +0,0 @@ +---- +--- Provide timestamp module. +--- create and manage x509 certificate sign request +--- @module ts +--- @usage +--- ts = require'openssl'.ts +--- +- +-do --define module function +- +---- create a new ts_req object. +--- @tparam[opt=1] integer version +--- @treturn ts_req timestamp sign request object +--- @see ts_req +-function req_new () end +- +---- read ts_req object from string or bio data +--- @tparam string|bio input +--- @treturn ts_req timestamp sign request object +--- @see ts_req +-function req_read() end +- +---- read ts_resp object from string or bio input +--- @tparam string|bio input +--- @treturn ts_resp object +-function resp_read() end +- +---- create ts_resp_ctx object +--- @tparam[opt] x509 signer timestamp certificate +--- @tparam[opt] evp_pkey pkey private key to sign ts_req +--- @tparam[opt] asn1_object|string|nid identity for default policy object +--- @treturn ts_resp_ctx object +- +-function resp_ctx_new() end +- +---- create ts_verify_ctx object +--- @tparam[opt=nil] string|ts_req reqdata +--- @treturn ts_verify_ctx object +-function verify_ctx_new() end +- +-end -- define module +- +-do -- define class +- +-------------------------------------------------------------------------------------------- +---- openssl.ts_req object +--- @type ts_req +- +-do -- define ts_req +- +---- export ts_req to string +--- @treturn string +-function export () end +- +---- get info as table +--- @treturn table +-function info() end +- +---- create ts_verify_ctx from ts_req object +--- @treturn ts_verify_ctx object +-function to_verify_ctx() end +- +---- make a clone of ts_req object +--- @treturn ts_req +-function dup() end +- +---- get version +--- @treturn integer +-function version() end +- +---- set version +--- @tparam integer version +--- @treturn boolean result +-function version() end +- +---- get cert_req +--- @treturn boolean true for set or not +-function cert_req() end +- +---- set cert_req +--- @tparam boolean cert_req +--- @treturn boolean result +-function cert_req() end +- +---- get nonce +--- @treturn bn openssl.bn object +-function nonce() end +- +---- set nonce +--- @tparam string|bn nonce +--- @treturn boolean result +-function nonce() end +- +---- get policy_id +--- @treturn asn1_object +-function policy_id() end +- +---- set policy_id +--- @tparam asn1_object|number id identity for asn1_object +--- @treturn boolean result +-function policy_id() end +- +---- get msg_imprint +--- @treturn string octet octet string +--- @treturn table with algorithm and paramater +-function msg_imprint() end +- +---- set msg_imprint +--- @tparam string data digest value of message +--- @tparam[opt='sha'] string|evp_md md_alg +--- @treturn boolean result +-function msg_imprint() end +- +-end --define class +- +- +---- openssl.ts_resp object +--- @type ts_resp +- +-do -- define ts_resp +- +---- export ts_resp to string +--- @treturn string +-function export () end +- +---- duplicate ts_resp object +--- @treturn ts_resp object +-function dup () end +- +---- get info as table +--- @treturn table +-function info() end +- +---- get info as table +--- @treturn table +-function tst_info() end +- +-end +- +---- openssl.ts_verify_ctx object +--- @type ts_verify_ctx +-do +---- verify ts_resp object, pkcs7 token or ts_resp data +--- @tparam ts_resp|pkcs7|string data +--- @treturn boolean result +-function verify() end +- +---- get x509_store cacerts +--- @treturn stack_of_x509 +-function store() end +- +---- set x509_store cacerts +--- @tparam x509_store cacerts +--- @treturn boolean result +-function store() end +- +---- get flags +--- @treturn integer flags +-function flags() end +- +---- set flags +--- @tparam integer flags +--- @treturn boolean result +-function flags() end +- +---- get untrust certs +--- @treturn stack_of_x509 untrust +-function certs() end +- +---- set untrust certs +--- @tparam stack_of_x509 untrust +--- @treturn boolean result +-function certs() end +- +---- get data +--- @treturn bio data object +-function data() end +- +---- set data +--- @tparam bio data object +--- @treturn boolean result +-function data() end +- +---- get imprint +--- @treturn string imprint +-function imprint() end +- +---- set imprint +--- @tparam string imprint +--- @treturn boolean result +-function imprint() end +- +-end +- +---- openssl.ts_resp_ctx object +--- @type ts_resp_ctx +- +-do +- +---- get signer cert and pkey +--- @treturn x509 cert object or nil +--- @treturn evp_pkey pkey object or nil +-function signer() end +- +---- set signer cert and pkey +--- @tparam x509 cert signer cert +--- @tparam evp_pkey pkey signer pkey +--- @treturn boolean result +-function signer() end +- +---- get additional certs +--- @treturn stack_of_x509 certs object or nil +-function certs() end +- +---- set additional certs +--- @tparam stack_of_x509 certs +--- @treturn boolean result +-function certs() end +- +---- get flags +--- @treturn integer flags +-function flags() end +- +---- set flags +--- @tparam integer flags +--- @treturn boolean result +-function flags() end +- +---- get policies +--- @treturn stack_of_asn1_object +-function policies() end +- +---- set policies +--- @tparam asn1_object|integer|string|stack_of_asn1_object|table policies +--- @treturn boolean result +-function policies() end +- +---- get accuracy +--- @treturn integer seconds +--- @treturn integer millis +--- @treturn integer micros +-function accuracy() end +- +---- set accuracy +--- @tparam integer seconds +--- @tparam integer millis +--- @tparam integer micros +--- @treturn boolean result +-function accuracy() end +- +---- get clock_precision_digits +--- @treturn integer clock_precision_digits +-function clock_precision_digits() end +- +---- set clock_precision_digits +--- @tparam integer clock_precision_digits +--- @treturn boolean result +-function clock_precision_digits() end +- +---- set status info +--- @tparam integer status +--- @tparam string text +--- @treturn boolean result +-function set_status_info() end +- +---- set status info cond +--- @tparam integer status +--- @tparam string text +--- @treturn boolean result +-function set_status_info_cond() end +- +---- add failure info +--- @tparam integer failure +--- @treturn result +-function add_failure_info() end +- +---- get all digest method +--- @treturn table contains all support digest method +-function md() end +- +---- set support digest method +--- @tparam table mds support digest method +--- @treturn boolean result +-function md() end +- +---- add digest +--- @tparam string|evp_digest md_alg +--- @treturn boolean result +-function md() end +- +---- get tst_info as table +--- @treturn table tst_info +-function tst_info() end +- +---- get ts_req object +--- @treturn rs_req +-function request() end +- +---- set serial generate callback function +--- @tparam function serial_cb serial_cb with proto funciont(ts_resp_ctx, arg) return openssl.bn end +--- @usage +--- function serial_cb(tsa,arg) +--- local bn = ... +--- return bn +--- end +--- local arg = {} +---- ts_resp_ctx:set_serial_cb(serial_cb, arg) +-function set_serial_cb() end +- +---- set time callback function +--- @tparam function time_cb serial_cb with proto funciont(ts_resp_ctx, arg) return sec, usec end +--- @usage +--- function time_cb(tsa,arg) +--- local time = os.time() +--- local utime = nil +--- return time,utime +--- end +--- local arg = {} +---- ts_resp_ctx:set_time_cb(time_cb, arg) +-function set_serial_cb() end +- +---- create response for ts_req +--- @tparam string|bio|ts_req data support string,bio ts_req content or ts_req object +--- @treturn ts_resp result +-function create_response() end +- +---- sign ts_req and get ts_resp, alias of create_response +--- @tparam string|bio|ts_req data support string,bio ts_req content or ts_req object +--- @treturn ts_resp result +-function sign() end +- +-end +- +-end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_attr.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_attr.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_attr.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_attr.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,121 +0,0 @@ +---- +--- Provide x509_attribute as lua object. +--- Sometime when you make CSR,TS or X509, you maybe need to use this. +--- +--- @module x509.attr +--- @usage +--- attr = require('openssl').x509.attr +--- +- +-do -- define module function +- +---- Create x509_attribute object +--- +--- @tparam table attribute with object, type and value +--- @treturn[1] x509_attribute mapping to X509_ATTRIBUTE in openssl +--- +--- @see x509_attribute_param_table +-function new_attribute() end +- +---- Create stack_of_x509_attribute object, which mapping to STACK_OF(X509_ATTRIBUTE) +--- +--- @tparam table node_array, each node is a x509_attribute node +--- @treturn sk_x509_attribute mapping to STACK_OF(X509_ATTRIBUTE) in openssl +--- +--- @see new_attribute, sk +-function new_sk_attribute() end +- +-end +- +-do -- define module table +- +---- x509_attribute contrust param table. +--- +--- @table x509_attribute_param_table +--- @tfield string|integer|asn1_object object, identify a asn1_object +--- @tfield string|integer type, same with type in asn1.new_string +--- @tfield string|asn1_object value, value of attribute +--- +--- @usage +--- xattr = x509.attr.new_attribute { +--- object = asn1_object, +--- type = Nid_or_String, +--- value = string or asn1_string value +--- } +--- +-function new_attribute() end +- +---- x509_attribute infomation table +--- +--- @table x509_attribute_info_table +--- @tfield asn1_object|object object of asn1_object +--- @tfield boolean single true for single value +--- @tfield table value if single, value is asn1_type or array have asn1_type node table +- +---- asn1_type object as table +--- +--- @table asn1_type_table +--- @tfield string value, value data +--- @tfield string type, type of value +--- @tfield string format, value is 'der', only exist when type is not in 'bit','bmp','octet' +--- +-end +- +-do -- define class +- +---- openssl.x509_attribute object +--- @type x509_attribute +--- +-do -- defint x509_attribute +- +---- get infomation table of x509_attribute. +--- +--- @treturn[1] table info, x509_attribute infomation as table +--- @see x509_attribute_info_table +-function info() end +- +---- clone then asn1_attribute +--- +--- @treturn x509_attribute attr clone of x509_attribute +-function dup() end +- +---- get type of x509_attribute. +--- +--- @tparam[opt] integer location which location to get type, default is 0 +--- @treturn[1] table asn1_type, asn1_type as table info +--- @treturn[2] nil nil, fail return nothing +--- +--- @see asn1_type_table +-function type() end +- +---- get asn1_object of x509_attribute. +--- +--- @treturn[1] asn1_object object of x509_attribute +-function object() end +- +---- set asn1_object for x509_attribute. +--- +--- @tparam asn1_object obj +--- @treturn[1] boolean true for success +--- @treturn[2] nil nil when occure error +--- @treturn[2] string errmsg error message +-function object() end +- +---- get type of x509_attribute +--- +--- @tparam integer idx location want to get type +--- @tparam string attrtype attribute type +--- @treturn asn1_string +-function data() end +- +---- set type of x509_attribute +--- +--- @tparam string attrtype attribute type +--- @tparam string data set to asn1_attr +--- @string data to set +-function data() end +- +-end +- +-end +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_crl.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_crl.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_crl.lua 2019-02-13 11:31:40.283968667 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_crl.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,157 +0,0 @@ +---- +--- Provide x509_crl as lua object. +--- create and manage x509 certificate sign request +--- @module x509.crl +--- @usage +--- crl = require'openssl'.x509.crl +--- +- +-do --define module function +- +---- create or generate a new x509_crl object. +--- Note if not give evp_pkey, will create a new x509_crl object,if give will generate a signed x509_crl object. +--- @tparam[opt] table revoked_list +--- @tparam[opt] x509 cacert ca cert to sign x509_crl +--- @tparam[opt] evp_pkey capkey private key to sign x509_crl +--- @tparam[opt] string|evp_md md_alg +--- @tparam[opt=7*24*3600] number period to generate new crl +--- @treturn x509_crl object +--- @see x509_crl +-function new() end +- +---- read x509_crl from string or bio input +--- @tparam bio|string input input data +--- @tparam[opt='auto'] string format support 'auto','pem','der' +--- @treturn x509_crl certificate sign request object +--- @see x509_crl +-function read() end +- +---- list all support reason info +--- @treturn table contain support reason node like {lname=...,sname=...,bitnum=...} +-function reason() end +- +-end -- define module +- +-do -- define class +- +---- openssl.x509_crl object +--- @type x509_crl +--- +- +-do -- define x509_crl +- +---- export x509_crl to string +--- @tparam[opt='pem'] string format +--- @tparam[opt='true'] boolean noext not export extension +--- @treturn string +-function export () end +- +---- sign x509_crl +--- @tparam evp_pkey pkey private key to sign x509 +--- @tparam x509|x509_name cacert or cacert x509_name +--- @tparam[opt='sha1WithRSAEncryption'] string|md_digest md_alg +--- @treturn boolean result true for check pass +-function sign() end +- +---- get digest of x509_crl +--- @tparam[opt='SHA1'] evp_md|string md_alg default use sha1 +--- @treturn string digest result +-function digest() end +- +---- compare with other x509_crl object +--- @tparam x509_crl other +--- @treturn boolean result true for equals or false +--- @usage +--- x:cmp(y) == (x==y) +-function cmp() end +- +---- make a delta x509_crl object +--- @tparam x509_crl newer +--- @tparam evp_pkey pkey +--- @tparam[opt='sha1'] evp_md|string md_alg +--- @tparam[opt=0] integer flags +--- @treturn x509_crl delta result x509_crl object +-function diff() end +- +---- check x509_crl with evp_pkey +--- @tparam evp_pkey pkey +--- @tparam[opt=0] integer flags +--- @treturn boolean result true for pass +-function check() end +- +---- parse x509_crl object as table +--- @tparam[opt=true] shortname default will use short object name +--- @treturn table result +-function parse() end +- +---- get count of revoked entry +--- @treturn number count +--- @usage +--- assert(#crl==crl:count()) +-function count() end +- +---- get revoekd entry +--- @tparam number index +--- @treturn table revoekd +-function get() end +- +---- set version key +--- @tparam integer version +--- @treturn boolean result +-function version() end +- +---- get issuer x509_name object +--- @treturn x509_name +-function issuer() end +- +---- set issuer x509_name object +--- @tparam x509_name|x509 issuer +--- @treturn boolean result +-function issuer() end +- +---- get lastUpdate time +--- @treturn string lastUpdate +-function lastUpdate() end +- +---- set lastUpdate time +--- @tparam number lastUpdate +--- @treturn boolean result +-function lastUpdate() end +- +---- get nextUpdate time +--- @treturn string nextUpdate +-function nextUpdate() end +- +---- set nextUpdate time +--- @tparam number nextUpdate +--- @treturn boolean result +-function nextUpdate() end +- +---- get updateTime time +--- @treturn string lastUpdate +--- @treturn string nextUpdate +-function updateTime() end +- +---- set updateTime time +--- @tparam[opt=os.time()] lastUpdate, default use current time +--- @tparam number periord periord how long time(seconds) +--- @treturn boolean result +-function updateTime() end +- +---- get extensions of x509_crl +--- @treturn stack_of_x509_extension extensions +-function extensions() end +- +---- set extensions to x509_crl object +--- @tparam stack_of_x509_extension extensions add to x509_crl +--- @treturn boolean result +-function extensions() end +- +---- add revoked entry to x509_crl object +--- @tparam string|number|bn serial +--- @tparam number revokedtime +--- @tparam[opt=0] number|string reason +--- @treturn boolean result true for add success +-function add() end +- +-end --define class +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_extension.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_extension.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_extension.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_extension.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,142 +0,0 @@ +---- +--- Provide x509_extension as lua object. +--- Sometime when you make CSR,TS or X509, you maybe need to use this. +--- +--- @module x509.extension +--- @usage +--- extension = require('openssl').x509.extension +--- +- +-do -- define module function +- +---- Create x509_extension object +--- +--- @tparam table extension with object, value and critical +--- @treturn x509_extension mapping to X509_EXTENSION in openssl +--- +--- @see x509_extension_param_table +-function new_extension() end +- +---- read der encoded x509_extension +--- @tparam string data der encoded +--- @treturn x509_extension mappling to X509_EXTENSION in openssl +-function read_extension() end +- +---- Create stack_of_x509_extension object, which mapping to STACK_OF(X509_EXTENSION) +--- +--- @tparam table node_array, each node is a x509_extension node +--- @treturn[1] sk_x509_extension mapping to STACK_OF(X509_EXTENSION) in openssl +--- +--- @see new_extension, sk +-function new_sk_extension() end +- +---- get all x509 certificate supported extensions +--- @treturn table contain all support extension nid +--- @treturn table contain all support extension info as table node {lname=..., sname=..., nid=...} +-function support() end +- +---- ask x509_extension object support or not +--- @tparam x509_extension extension +--- @tparam boolean true for supported, false or not +-function support() end +- +---- ask nid or name support or not +--- @tparam number|string nid_or_name for extension +--- @tparam boolean true for supported, false or not +-function support() end +- +-end +- +-do -- define module table +- +---- x509_extension contrust param table. +--- +--- @table x509_extension_param_table +--- @tfield boolean critical true set critical +--- @tfield asn1_string value of x509_extension +--- @tfield string|asn1_object object, object of extension +--- +--- @usage +--- xattr = x509.attr.new_extension { +--- object = asn1_object, +--- critical = false, +--- value = string or asn1_string value +--- } +-function new_extension() end +- +---- x509_extension infomation table +--- other field is number type, and value table is alter name.(I not understand clearly) +--- @table x509_extension_info_table +--- @tfield asn1_object|object object of x509_extension +--- @tfield boolean|critical true for critical value +--- @tfield string|value as octet string +- +- +-end +- +-do -- define class +- +---- openssl.x509_extension object +--- @type x509_extension +--- +-do -- defint x509_extension +- +---- get infomation table of x509_extension. +--- +--- @tparam[opt] boolean|utf8 true for utf8 default +--- @treturn[1] table info, x509_extension infomation as table +--- @see x509_extension_info_table +-function info() end +- +---- clone then x509_extension +--- +--- @treturn x509_extension attr clone of x509_extension +-function dup() end +- +---- get critical of x509_extension. +--- +--- @treturn boolean true if extension set critical or false +-function critical() end +- +---- set critical of x509_extension. +--- +--- @tparam boolean critical set to self +--- @treturn[1] boolean set critical success return true +--- @treturn[2] nil nil, fail return nothing +--- @treturn[2] string errmsg reason of fail +-function critical() end +- +---- get asn1_object of x509_extension. +--- +--- @treturn[1] asn1_object object of x509_extension +-function object() end +- +---- set asn1_object for x509_extension. +--- +--- @tparam asn1_object obj +--- @treturn[1] boolean true for success +--- @treturn[2] nil nil when occure error +--- @treturn[2] string errmsg error message +-function object() end +- +---- get data of x509_extension +--- +--- @treturn asn1_string +-function data() end +- +---- set type of x509_extension +--- +--- @tparam asn1_string data set to self +--- @treturn[1] boolean true for success +--- @treturn[2] nil nil when occure error +--- @treturn[2] string errmsg error message +-function data() end +- +---- export x509_extenion to der encoded string +--- @treturn string +-function export() end +- +-end +- +-end +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509.lua 2019-02-13 11:31:40.283968667 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,187 +0,0 @@ +---- +--- Provide x509 module. +--- create and manage x509 certificate +--- @module x509 +--- @usage +--- x509 = require'openssl'.x509 +--- +- +-do --define module function +- +---- create or generate a new x509 object. +--- @tparam[opt] openssl.bn serial serial number +--- @tparam[opt] x509_req csr,copy x509_name, pubkey and extension to new object +--- @tparam[opt] x509_name subject subject name set to x509_req +--- @tparam[opt] stack_of_x509_extension extensions add to x509 +--- @tparam[opt] stack_of_x509_attribute attributes add to x509 +--- @treturn x509 certificate object +-function new() end +- +---- read x509 from string or bio input +--- @tparam bio|string input input data +--- @tparam[opt='auto'] string format support 'auto','pem','der' +--- @treturn x509 certificate object +-function read() end +- +---- return all supported purpose as table +--- @treturn table +-function purpose() end +- +---- get special purpose info as table +--- @tparam number|string purpose id or short name +--- @treturn table +-function purpose() end +- +---- get support certtypes +--- @tparam[opt='standard'] string type support 'standard','netscape','extend' +--- @treturn table if type is 'standard' or 'netscape', contains node with {lname=...,sname=...,bitname=...}, +--- if type is 'extend', contains node with {lname=...,sname=...,nid=...} +-function certtypes() end +- +---- get certificate verify result string message +--- @tparam number verify_result +--- @treturn string result message +-function verify_cert_error_string() end +- +-end --define module +- +-do -- define class +- +---- openssl.x509 object +--- @type x509 +--- +- +-do -- define x509 +- +---- export x509_req to string +--- @tparam[opt='pem'] string format, 'der' or 'pem' default +--- @tparam[opt='true'] boolean noext not export extension +--- @treturn string +-function export() end +- +---- parse x509 object as table +--- @tparam[opt=true] shortname default will use short object name +--- @treturn table result which all x509 information +-function parse() end +- +---- sign x509 +--- @tparam evp_pkey pkey private key to sign x509 +--- @tparam x509|x509_name cacert or cacert x509_name +--- @tparam[opt='sha1WithRSAEncryption'] string|md_digest md_alg +--- @treturn boolean result true for check pass +-function sign() end +- +---- check x509 with evp_pkey +--- @tparam evp_pkey pkey private key witch match with x509 pubkey +--- @treturn boolean result true for check pass +-function check() end +- +---- check x509 with ca certchian and option purpose +--- purpose can be one of: ssl_client, ssl_server, ns_ssl_server, smime_sign, smime_encrypt, crl_sign, any, ocsp_helper, timestamp_sign +--- @tparam x509_store cacerts +--- @tparam x509_store untrusted certs containing a bunch of certs that are not trusted but may be useful in validating the certificate. +--- @tparam[opt] string purpose to check supported +--- @treturn boolean result true for check pass +--- @treturn integer verify result +--- @see verify_cert_error_string +-function check() end +- +---- get digest of x509 object +--- @tparam[opt='sha1'] evp_digest|string md_alg, default use 'sha1' +--- @treturn string digest result +-function digest() end +- +---- get public key of x509 +--- @treturn evp_pkey public key +-function pubkey() end +- +---- set public key of x509 +--- @tparam evp_pkey pubkey public key set to x509 +--- @treturn boolean result, true for success +-function pubkey() end +- +---- get extensions of x509 object +--- @tparam[opt=false] boolean asobject, true for return as stack_of_x509_extension or as table +--- @treturn[1] stack_of_x509_extension object when param set true +--- @treturn[2] table contain all x509_extension when param set false or nothing +-function extensions() end +- +---- set extension of x509 object +--- @tparam stack_of_x509_extension extensions +--- @treturn boolean result true for success +-function extensions() end +- +---- get issuer name of x509 +--- @tparam[opt=false] boolean asobject, true for return as x509_name object, or as table +--- @treturn[1] x509_name issuer +--- @treturn[1] table issuer name as table +-function issuer() end +- +---- set issuer name of x509 +--- @tparam x509_name name +--- @treturn boolean result true for success +-function issuer() end +- +---- get subject name of x509 +--- @tparam[opt=false] boolean asobject, true for return as x509_name object, or as table +--- @treturn[1] x509_name subject name +--- @treturn[1] table subject name as table +-function subject() end +- +---- set subject name of x509 +--- @tparam x509_name subject +--- @treturn boolean result true for success +-function subject() end +- +---- get serial number of x509 +--- @tparam[opt=true] boolean asobject +--- @treturn[1] bn object +--- @treturn[2] string result +-function serial() end +- +---- set serial number of x509 +--- @tparam string|number|bn serail +--- @treturn boolean result true for success +-function serial() end +- +---- get version number of x509 +--- @treturn number version of x509 +-function version() end +- +---- set version number of x509 +--- @tparam number version +--- @treturn boolean result true for result +-function version() end +- +---- get notbefore valid time of x509 +--- @treturn string notbefore time string +-function notbefore() end +- +---- set notbefore valid time of x509 +--- @tparam string|number notbefore +-function notbefore() end +- +---- get notafter valid time of x509 +--- @treturn string notafter time string +-function notafter() end +- +---- set notafter valid time of x509 +--- @tparam string|number notafter +-function notafter() end +- +---- check x509 valid +--- @tparam[opt] number time, default will use now time +--- @treturn boolean result true for valid, or for invalid +--- @treturn string notbefore +--- @treturn string notafter +-function validat() +- +---- set valid time, notbefore and notafter +--- @tparam number notbefore +--- @tparam number notafter +--- @treturn boolean result, true for success +-function validat() end +- +-end --define x509 +- +-end --define class +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_name.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_name.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_name.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_name.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,144 +0,0 @@ +---- +--- Provide x509_name as lua object. +--- Sometime when you make CSR,TS or X509, you maybe need to use this. +--- +--- @module x509.name +--- @usage +--- name = require('openssl').x509.name +--- +- +- +-do -- define module function +- +---- Create x509_name object +--- +--- @tparam table array include name node +--- @tparam[opt] boolean utf8 encode will be use default +--- @treturn x509_name mapping to X509_EXTENSION in openssl +--- @usage +--- name = require'openssl'.x509.name +--- subject = name.new{ +--- {C='CN'}, +--- {O='kkhub.com'}, +--- {CN='zhaozg'} +--- } +--- +- +-function new() end +- +---- Create x509_name from der string +--- +--- @tparam string content DER encoded string +--- @treturn x509_name mapping to X509_NAME in openssl +--- +-function d2i() end +- +-end +- +-do -- define module table +--- +---- x509_name infomation table +--- other field is number type, and value table is alter name.(I not understand clearly) +--- @table x509_extension_info_table +--- @tfield asn1_object|object object of x509_name +--- @tfield boolean|critical true for critical value +--- @tfield string|value as octet string +- +- +-end +- +-do -- define class +- +---- openssl.x509_name object +--- @type x509_name +--- +-do -- define x509_name +- +---- as oneline of x509_name. +--- +--- @treturn string line, name as oneline text +-function oneline() end +- +---- get hash code of x509_name +--- +--- @treturn integer hash hash code of x509_name +-function hash() end +- +---- get digest of x509_name +--- +--- @tparam string|nid|openssl.evp_md md method of digest +--- @treturn string digest digest value by given alg of x509_name +-function digest() end +- +---- print x509_name to bio object +--- +--- @tparam openssl.bio out output bio object +--- @tparam[opt] integer indent for output +--- @tparam[opt] integer flags for output +--- @treturn boolean result, follow by error message +-function print() end +- +---- return x509_name as table +--- +--- @tparam boolean utf8 true for utf8 encoded string, default +--- @treturn table names +--- @see new +-function info() end +- +---- compare two x509_name +--- +--- @tparam x509_name another to compare with +--- @treturn boolean result true for equal or false +--- @usage +--- +--- name1 = name.new({...}) +--- name2 = name1:dup() +--- assert(name1:cmp(name2)==(name1==name2)) +--- +-function cmp() end +- +---- get DER encoded string of x509_name. +--- +--- @treturn string der +-function i2d() end +- +---- get count in x509_name. +--- +--- @treturn integer count of x509_name +-function entry_count() end +- +---- get text by given asn1_object or nid +--- +--- @tparam string|integer|asn1_object identid for asn1_object +--- @tparam[opt=-1] number lastpos retrieve the next index after lastpos +--- @treturn string +--- @treturn lastpos +-function get_text() end +- +---- get x509 name entry by index +--- @tparam integer index start from 0, and less than xn:entry_count() +--- @tparam[opt=true] boolean utf8 +--- @treturn x509 name entry table +-function get_entry() end +- +---- add name entry +--- +--- @tparam string|integer|asn1_object identid for asn1_object +--- @tparam string data to add +--- @tparam[opt] boolean utf8 true for use utf8 default +--- @treturn boolean result true for success or follow by error message +-function add_entry() end +- +---- get index by give asn1_object or nid +--- +--- @tparam integer location which name entry to delete +--- @treturn[1] asn1_object object that delete name entry +--- @treturn[1] asn1_string value that delete name entry +--- @treturn[2] nil delete nothing +-function delete_entry() end +- +- +-end +- +-end +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_req.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_req.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_req.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_req.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,119 +0,0 @@ +---- +--- Provide x509_req as lua object. +--- create and manage x509 certificate sign request +--- @module x509.req +--- @usage +--- req = require'openssl'.x509.req +--- +- +-do --define module function +- +---- create or generate a new x509_req object. +--- Note if not give evp_pkey, will create a new x509_req object,or will generate a signed x509_req object. +--- @tparam[opt] x509_name subject subject name set to x509_req +--- @tparam[opt] stack_of_x509_extension extensions add to x509_req +--- @tparam[opt] stack_of_x509_attribute attributes add to x509_req +--- @tparam[opt] evp_pkey pkey private key sign the x509_req, and set as public key +--- @tparam[opt='sha1WithRSAEncryption'] evp_digest|string md_alg, only used when pkey exist, and should fellow pkey +--- @treturn x509_req certificate sign request object +--- @see x509_req +-function new () end +- +---- read x509_req from string or bio input +--- @tparam bio|string input input data +--- @tparam[opt='auto'] string format support 'auto','pem','der' +--- @treturn x509_req certificate sign request object +-function read() end +- +-end -- define module +- +-do -- define class +- +---- openssl.x509_req object +--- @type x509_req +--- +- +-do -- define x509_req +- +---- export x509_req to string +--- @tparam[opt='pem'] string format +--- @tparam[opt='true'] boolean noext not export extension +--- @treturn string +-function export () end +- +---- get public key +--- @treturn evp_pkey public key +-function public() end +- +---- set public key +--- @tparam evp_pkey pubkey public key set to x509_req +--- @treturn boolean result +-function public() end +- +---- get version key +--- @treturn integer +-function version() end +- +---- set version key +--- @tparam integer version +--- @treturn boolean result +-function version() end +- +---- get subject x509_name object +--- @treturn x509_name +-function subject() end +- +---- set subject x509_name object +--- @tparam x509_name subject +--- @treturn boolean result +-function subject() end +- +---- remove attribute object from location +--- @tparam integer location +--- @tparam nil nil, nil not none +--- @treturn x509_attribute attribute removed +-function attribute() end +- +---- get attribute object from location +--- @tparam integer location +--- @treturn x509_attribute attribute +-function attribute() end +- +---- add attribute to x509_req object +--- @tparam x509_attribute attribute attribute to add +--- @treturn boolean result +-function attribute() end +- +---- get total attribute count in x509_req object +--- @treturn integer +-function attr_count() end +- +---- convert x509_req to x509 object +--- @treturn x509 object not signed +--- @fixme memleaks +-function to_x509() +- +---- clone x509_req object +--- @treturn x509_req object +-function dup() +- +---- check x509_req with evp_pkey +--- @tparam evp_pkey pkey +--- @treturn boolean result true for check pass +-function check() end +- +---- verify x509_req signature +--- @treturn boolean result true for verify pass +-function verify() end +- +---- get digest of x509_req +--- @tparam[opt='SHA1'] evp_md|string md_alg default use sha1 +--- @treturn string digest result +-function digest() end +- +---- parse x509_req object as table +--- @tparam[opt=true] shortname default will use short object name +--- @treturn table result +-function parse() end +- +-end --define class +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_store.lua luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_store.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/ldoc/x509_store.lua 2019-02-13 11:31:40.280635356 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/ldoc/x509_store.lua 1970-01-01 01:00:00.000000000 +0100 +@@ -1,69 +0,0 @@ +---- +--- Provide x509_store as lua object. +--- create and manage x509 store object +--- @module x509.store +--- @usage +--- store = require'openssl'.x509.store +--- +- +-do --define module function +- +---- create or generate a new x509_store object. +--- @tparam table certs array of x509 objects, all x509 object will add to store, certs can be empty but not nil +--- @tparam[opt] table crls array of x509_crl objects, all crl object will add to store +--- @treturn x509_store object +--- @see x509_store +-function new() end +- +-end -- define module +- +-do -- define class +- +---- openssl.x509_store object +--- @type x509_store +--- +- +-do -- define x509_store +- +-function export () end +- +---- set verify depth of certificate chains +--- @tparam number depth +--- @treturn boolean result +-function depth() end +- +---- set verify flags of certificate chains +--- @tparam number flags +--- @treturn boolean result +-function flags() end +- +---- set as trust x509 store +--- @tparam boolean trust +--- @treturn boolean result +-function trust() end +- +---- set prupose of x509 store +--- @tparam integer purpose +--- @treturn boolean result +-function purpose() end +- +---- load certificate from file or dir,not given any paramater will load from defaults path +--- @tparam[opt] string filepath +--- @tparam[opt] string dirpath +--- @treturn boolean result +-function load() end +- +---- add x509 certificate or crl to store +--- paramater support x509 object,x509_crl object or array contains x509,x509_crl object +--- @treturn boolean result +-function add(...) end +- +---- add lookup path for store +--- @tparam string path file or dir path to add +--- @tparam[opt='file'] mode only 'file' or 'dir' +--- @tparam[opt='default'] format only 'pem', 'der' or 'default' +--- @treturn boolean result +-function add_lookup() end +- +-end --define class +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/lib/luv/ssl.lua luvi-src-v2.7.6/deps/lua-openssl/lib/luv/ssl.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/lib/luv/ssl.lua 2019-02-13 11:31:40.277302045 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/lib/luv/ssl.lua 2019-02-13 11:53:24.105128513 +0100 +@@ -1,240 +1,246 @@ +-local uv = require('luv') +-local openssl=require'openssl' +-local ssl,bio,x509,pkey,csr = openssl.ssl,openssl.bio,openssl.x509,openssl.pkey,openssl.csr ++local uv = require 'luv' ++local openssl = require 'openssl' ++local ssl, bio, x509, pkey, csr = openssl.ssl, openssl.bio, openssl.x509, openssl.pkey, openssl.csr + +-local bit = require'bit' ++local bit = require 'bit' + local print = print +--- support ++-- support + local M = {} + +-local function load(path) +- local f = io.open(path,'rb') +- if f then +- local c = f:read('*a') +- f:close() +- return c +- end ++local function load (path) ++ local f = io.open(path, 'rb') ++ if f then ++ local c = f:read '*a' ++ f:close() ++ return c ++ end + end + +-function M.new_ctx(params) +- params = params or {} +- local protocol = params.protocol or 'SSLv3_client' +- local ctx = ssl.ctx_new(protocol, params.ciphers) +- +- local xkey,xcert = nil,nil +- +- if (params.certificate) then +- xcert = assert(x509.read(load(params.certificate))) +- end +- +- if params.key then +- if (type(params.password)=='nil') then +- xkey = assert(pkey.read(load(params.key),true,'pem')) +- elseif (type(params.password)=='string') then +- xkey = assert(pkey.read(load(params.key),true,'pem',params.password)) +- elseif (type(params.password)=='function') then +- local p = assert(params.password()) +- xkey = assert(pkey.read(load(params.key),true,'pem',p)) +- end +- assert(ctx:use(xkey, xcert)) +- end +- +- if(params.cafile or params.capath) then +- ctx:verify_locations(params.cafile,params.capath) +- end +- +- local unpack = unpack or table.unpack +- if(params.verify) then +- ctx:verify_mode(params.verify) +- end +- if params.options and #params.options>0 then +- local args = {} +- for i=1,#params.options do +- table.insert(arg,params.options[i]) +- end +- ctx:options(ssl.none) +- end +- +- if params.verifyext then +- ctx:set_cert_verify(params.verifyext) +- end +- if params.dhparam then +- ctx:set_tmp('dh',params.dhparam) +- end +- if params.curve then +- ctx:set_tmp('ecdh',params.curve) +- end +- return ctx ++function M.new_ctx (params) ++ params = params or {} ++ local protocol = params.protocol or 'SSLv3_client' ++ local ctx = ssl.ctx_new(protocol, params.ciphers) ++ ++ local xkey, xcert = nil, nil ++ ++ if params.certificate then ++ local ctx = assert(load(params.certificate)) ++ xcert = assert(x509.read(ctx)) ++ end ++ ++ if params.key then ++ if type(params.password) == 'nil' then ++ xkey = assert(pkey.read(load(params.key), true, 'pem')) ++ elseif type(params.password) == 'string' then ++ xkey = assert(pkey.read(load(params.key), true, 'pem', params.password)) ++ elseif type(params.password) == 'function' then ++ local p = assert(params.password()) ++ xkey = assert(pkey.read(load(params.key), true, 'pem', p)) ++ end ++ assert(ctx:use(xkey, xcert)) ++ end ++ ++ if params.cafile or params.capath then ++ ctx:verify_locations(params.cafile, params.capath) ++ end ++ ++ local unpack = unpack or table.unpack ++ if params.verify then ++ ctx:verify_mode(params.verify) ++ end ++ if params.options and #params.options > 0 then ++ local args = {} ++ for i = 1, #params.options do ++ table.insert(arg, params.options[i]) ++ end ++ ctx:options(ssl.none) ++ end ++ ++ if params.verifyext then ++ ctx:set_cert_verify(params.verifyext) ++ end ++ if params.dhparam then ++ ctx:set_tmp('dh', params.dhparam) ++ end ++ if params.curve then ++ ctx:set_tmp('ecdh', params.curve) ++ end ++ return ctx + end + + local S = {} + S.__index = { ++ handshake = function (self, connected_cb) ++ if not self.connecting then ++ uv.read_start(self.socket, function (err, chunk) ++ if err then ++ print('ERR', err) ++ self:onerror(err) ++ end ++ if chunk then ++ self.inp:write(chunk) ++ self:handshake(connected_cb) ++ else ++ self:close() ++ end ++ end) ++ ++ self.connecting = true ++ end ++ if not self.connected then ++ local ret, err = self.ssl:handshake() ++ if ret == nil then ++ if self.onerror then ++ self:onerror() ++ elseif self.onclose then ++ self:onclose() ++ else ++ self:close() ++ end ++ else ++ local i, o = self.out:pending() ++ if i > 0 then ++ --client handshake ++ uv.write(self.socket, self.out:read(), function () ++ self:handshake(connected_cb) ++ end) ++ return ++ end ++ if ret == false then ++ return ++ end + +- handshake = function(self, connected_cb) +- if not self.connecting then +- uv.read_start(self.socket, function(err,chunk) +- if(err) then +- print('ERR',err) +- self:onerror(err) +- end +- if chunk then +- self.inp:write(chunk) +- self:handshake(connected_cb) +- else +- self:close() ++ self.connected = true ++ uv.read_stop(self.socket) ++ uv.read_start(self.socket, function (err, chunk) ++ if err then ++ print('ERR', err) ++ self:onerror() ++ end ++ if chunk then ++ local ret, err = self.inp:write(chunk) ++ if ret == nil then ++ if self.onerror then ++ self.onerror(self) ++ elseif self.onend then ++ self.onend(self) + end +- end) ++ return ++ end + +- self.connecting = true +- end +- if not self.connected then +- local ret,err = self.ssl:handshake() +- if ret==nil then +- if (self.onerror) then +- self:onerror() +- elseif (self.onclose) then +- self:onclose() +- else +- self:close() ++ while self.connected and self.inp:pending()>0 do ++ if o > 0 then ++ assert(false, 'never here') + end +- else +- local i, o = self.out:pending() +- if i > 0 then --�ͻ�������ʹ�� +- uv.write(self.socket, self.out:read(), function() +- self:handshake(connected_cb) +- end) +- return ++ local ret, msg = self.ssl:read() ++ if ret then ++ self:ondata(ret) + end +- if (ret==false) then return end +- +- self.connected = true +- uv.read_stop(self.socket) +- uv.read_start(self.socket, function(err,chunk) +- if(err) then +- print('ERR',err) +- self:onerror() +- end +- if chunk then +- local ret,err = self.inp:write(chunk) +- if ret==nil then +- if self.onerror then +- self.onerror(self) +- elseif self.onend then +- self.onend(self) +- end +- return +- end +- +- local i,o = self.inp:pending() +- while i>0 do +- if o > 0 then +- assert(false,'never here') +- end +- local ret, msg = self.ssl:read() +- if ret then +- self:ondata(ret) +- end +- i,o = self.inp:pending() +- end +- else +- self:close() +- end +- end) +- connected_cb(self) +- end +- +- return self.connected +- end +- end, +- shutdown = function(self,callback) +- if not self.shutdown then +- self.ssl:shutdown() +- self.socket:shutdown() +- if callback then +- callback(self) +- end +- self.shutdown = true +- end +- end, +- close = function(self) +- if self.connected then +- if self.onclose then +- self.onclose(self) +- end +- self:shutdown() +- if self.ssl then +- self.ssl:shutdown() +- end +- self.ssl = nil +- if self.inp then self.inp:close() end +- if self.out then self.out:close() end +- +- self.out,self.inp = nil,nil +- uv.close(self.socket) +- self.connected = nil +- self.socket = nil +- end +- end, +- write = function(self,data,cb) +- if not self.ssl then +- return +- end +- local ret,err = self.ssl:write(data) +- if ret==nil then +- if self.onerror then +- self.onerror(self) +- elseif self.onend then +- self.onend(self) ++ end ++ else ++ self:close() + end +- return +- end +- local i,o = self.out:pending() +- if i>0 then +- uv.write(self.socket,self.out:read(),cb) +- end +- if o > 0 then +- assert(false,'never here') +- end ++ end) ++ connected_cb(self) ++ end ++ ++ return self.connected ++ end ++ end, ++ shutdown = function (self, callback) ++ if not self.shutdown then ++ self.ssl:shutdown() ++ self.socket:shutdown() ++ if callback then ++ callback(self) ++ end ++ self.shutdown = true ++ end ++ end, ++ close = function (self) ++ if self.connected then ++ if self.onclose then ++ self.onclose(self) ++ end ++ self:shutdown() ++ if self.ssl then ++ self.ssl:shutdown() ++ end ++ self.ssl = nil ++ if self.inp then ++ self.inp:close() ++ end ++ if self.out then ++ self.out:close() ++ end ++ ++ self.out, self.inp = nil, nil ++ uv.close(self.socket) ++ self.connected = nil ++ self.socket = nil ++ end ++ end, ++ write = function (self, data, cb) ++ if not self.ssl then ++ return ++ end ++ local ret, err = self.ssl:write(data) ++ if ret == nil then ++ if self.onerror then ++ self.onerror(self) ++ elseif self.onend then ++ self.onend(self) ++ end ++ return ++ end ++ local i, o = self.out:pending() ++ if i > 0 then ++ uv.write(self.socket, self.out:read(), cb) + end ++ if o > 0 then ++ assert(false, 'never here') ++ end ++ end, ++ + } + +-function M.new_ssl(ctx,socket,server) +- local s = {} +- s.inp,s.out = bio.mem(8192),bio.mem(8192) +- s.socket = socket +- s.mode = server and server or false +- s.ssl = ctx:ssl(s.inp,s.out,s.mode) +- uv.tcp_nodelay(socket,true) +- +- setmetatable(s,S) +- return s ++function M.new_ssl (ctx, socket, server) ++ local s = {} ++ s.inp, s.out = bio.mem(8192), bio.mem(8192) ++ s.socket = socket ++ s.mode = server and server or false ++ s.ssl = ctx:ssl(s.inp, s.out, s.mode) ++ uv.tcp_nodelay(socket, true) ++ ++ setmetatable(s, S) ++ return s + end + +-function M.connect(host,port,ctx,connected_cb) +- if type(ctx)=='table' then +- ctx = ssl.new_ctx(ctx) +- end +- local socket = uv.new_tcp() +- local scli = M.new_ssl(ctx, socket) +- +- uv.tcp_connect(socket, host, port, function(self, err) +- if err then +- print('ERROR',err) +- else +- print('SCLI',scli) +- scli:handshake(function(self) +- if connected_cb then +- connected_cb(self) +- end +- end) +- end ++function M.connect (host, port, ctx, connected_cb) ++ if type(ctx) == 'table' then ++ ctx = ssl.new_ctx(ctx) ++ end ++ local socket = uv.new_tcp() ++ local scli = M.new_ssl(ctx, socket) ++ ++ uv.tcp_connect(socket, host, port, function (self, err) ++ if err then ++ print('ERROR', err) ++ else ++ print('SCLI', scli) ++ scli:handshake(function (self) ++ if connected_cb then ++ connected_cb(self) ++ end ++ end) ++ end + end) + +- return scli ++ return scli + end + +-function M.error() +- return openssl.error(true) ++function M.error () ++ return openssl.error(true) + end + + return M +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/Makefile luvi-src-v2.7.6/deps/lua-openssl/Makefile +--- luvi-src-v2.7.6.orig/deps/lua-openssl/Makefile 2019-02-13 11:31:40.273968734 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/Makefile 2019-02-13 11:53:24.105128513 +0100 +@@ -1,85 +1,121 @@ +-T=openssl +- +-PREFIX ?=/usr/local +-LIB_OPTION ?= -shared +- +-#Lua auto detect +-LUA_VERSION ?= $(shell pkg-config luajit --print-provides) +-ifeq ($(LUA_VERSION),) ############ Not use luajit +-LUAV ?= $(shell lua -e "_,_,v=string.find(_VERSION,'Lua (.+)');print(v)") +-LUA_CFLAGS ?= -I$(PREFIX)/include/lua$(LUAV) +-LUA_LIBS ?= -L$(PREFIX)/lib +-LUA_LIBDIR ?= $(PREFIX)/lib/lua/$(LUAV) +-else +-LUAV ?= $(shell lua -e "_,_,v=string.find(_VERSION,'Lua (.+)');print(v)") +-LUA_CFLAGS ?= $(shell pkg-config luajit --cflags) +-LUA_LIBS ?= $(shell pkg-config luajit --libs) +-LUA_LIBDIR ?= $(PREFIX)/lib/lua/$(LUAV) +-endif +- +-#OS auto detect +-SYS := $(shell gcc -dumpmachine) +- +-ifneq (, $(findstring linux, $(SYS))) +-# Do linux things +-LDFLAGS = -fPIC -lrt -ldl +-OPENSSL_LIBS ?= $(shell pkg-config openssl --libs) +-OPENSSL_CFLAGS ?= $(shell pkg-config openssl --cflags) +-CFLAGS = -fPIC $(OPENSSL_CFLAGS) $(LUA_CFLAGS) +-endif +-ifneq (, $(findstring apple, $(SYS))) +-# Do darwin things +-LDFLAGS = -fPIC -lrt -ldl +-OPENSSL_LIBS ?= $(shell pkg-config openssl --libs) +-OPENSSL_CFLAGS ?= $(shell pkg-config openssl --cflags) +-CFLAGS = -fPIC $(OPENSSL_CFLAGS) $(LUA_CFLAGS) +-endif +-ifneq (, $(findstring mingw, $(SYS))) +-# Do mingw things +-V = $(shell lua -e "v=string.gsub('$(LUAV)','%.','');print(v)") +-LDFLAGS = -mwindows -lcrypt32 -lssl -lcrypto -lws2_32 $(PREFIX)/bin/lua$(V).dll +-LUA_CFLAGS = -DLUA_LIB -DLUA_BUILD_AS_DLL -I$(PREFIX)/include/ +-CFLAGS = $(OPENSSL_CFLAGS) $(LUA_CFLAGS) +-endif +-ifneq (, $(findstring cygwin, $(SYS))) +-# Do cygwin things +-OPENSSL_LIBS ?= $(shell pkg-config openssl --libs) +-OPENSSL_CFLAGS ?= $(shell pkg-config openssl --cflags) +-CFLAGS = -fPIC $(OPENSSL_CFLAGS) $(LUA_CFLAGS) +-endif +-#custome config +-ifeq (.config, $(wildcard .config)) +-include .config +-endif +- +-LIBNAME= $T.so.$V +- +-#LIB_OPTION= -bundle -undefined dynamic_lookup #for MacOS X +- +-# Compilation directives +-WARN_MOST = -Wall -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -pedantic +-WARN = -Wall -Wno-unused-value +-WARN_MIN = +-CFLAGS += $(WARN_MIN) -DPTHREADS +-CC= gcc -g $(CFLAGS) -Ideps +- +- +-OBJS=src/asn1.o src/auxiliar.o src/bio.o src/cipher.o src/cms.o src/compat.o src/crl.o src/csr.o src/dh.o src/digest.o src/dsa.o \ +-src/ec.o src/engine.o src/hmac.o src/lbn.o src/lhash.o src/misc.o src/ocsp.o src/openssl.o src/ots.o src/pkcs12.o src/pkcs7.o \ +-src/pkey.o src/rsa.o src/ssl.o src/th-lock.o src/util.o src/x509.o src/xattrs.o src/xexts.o src/xname.o src/xstore.o src/xalgor.o src/callback.o +- +-.c.o: +- $(CC) -c -o $@ $? +- +-all: $T.so +- echo $(SYS) +- +-$T.so: $(OBJS) +- MACOSX_DEPLOYMENT_TARGET="10.3"; export MACOSX_DEPLOYMENT_TARGET; $(CC) $(CFLAGS) $(LIB_OPTION) -o $T.so $(OBJS) $(OPENSSL_LIBS) $(LUA_LIBS) $(LDFLAGS) +- +-install: all +- mkdir -p $(LUA_LIBDIR) +- cp $T.so $(LUA_LIBDIR) +- +-clean: +- rm -f $T.so $(OBJS) ++T=openssl ++ ++PREFIX ?=/usr/local ++CC := $(CROSS)$(CC) ++AR := $(CROSS)$(AR) ++LD := $(CROSS)$(LD) ++ ++#OS auto detect ++ifneq (,$(TARGET_SYS)) ++ SYS := $(TARGET_SYS) ++else ++ SYS := $(shell gcc -dumpmachine) ++endif ++ ++#Lua auto detect ++LUA_VERSION := $(shell pkg-config luajit --print-provides) ++ifeq ($(LUA_VERSION),) ++ # Not found luajit package, try lua ++ LUA_VERSION := $(shell pkg-config lua --print-provides) ++ ifeq ($(LUA_VERSION),) ++ # Not found lua package, try from prefix ++ LUA_VERSION := $(shell lua -e "_,_,v=string.find(_VERSION,'Lua (.+)');print(v)") ++ LUA_CFLAGS ?= -I$(PREFIX)/include/lua$(LUA_VERSION) ++ LUA_LIBS ?= -L$(PREFIX)/lib -llua ++ LUA_LIBDIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION) ++ else ++ # Found lua package ++ LUA_VERSION := $(shell lua -e "_,_,v=string.find(_VERSION,'Lua (.+)');print(v)") ++ LUA_CFLAGS ?= $(shell pkg-config lua --cflags) ++ LUA_LIBS ?= $(shell pkg-config lua --libs) ++ LUA_LIBDIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION) ++ endif ++else ++ # Found luajit package ++ LUA_VERSION := $(shell luajit -e "_,_,v=string.find(_VERSION,'Lua (.+)');print(v)") ++ LUA_CFLAGS ?= $(shell pkg-config luajit --cflags) ++ LUA_LIBS ?= $(shell pkg-config luajit --libs) ++ LUA_LIBDIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION) ++endif ++ ++#OpenSSL auto detect ++OPENSSL_CFLAGS ?= $(shell pkg-config openssl --cflags) ++OPENSSL_LIBS ?= $(shell pkg-config openssl --static --libs) ++ ++ifneq (, $(findstring linux, $(SYS))) ++ # Do linux things ++ CFLAGS = -fpic ++ LDFLAGS = -Wl,--no-undefined -fpic -lrt -ldl -lm ++endif ++ ++ifneq (, $(findstring apple, $(SYS))) ++ # Do darwin things ++ CFLAGS = -fPIC ++ LDFLAGS = -fPIC -undefined dynamic_lookup -ldl ++ #MACOSX_DEPLOYMENT_TARGET="10.3" ++ CC := MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} $(CC) ++endif ++ ++ifneq (, $(findstring mingw, $(SYS))) ++ # Do mingw things ++ CFLAGS = -DLUA_LIB -DLUA_BUILD_AS_DLL -DWIN32_LEAN_AND_MEAN ++endif ++ ++ifneq (, $(findstring cygwin, $(SYS))) ++ # Do cygwin things ++ CFLAGS = -fPIC ++endif ++ ++ifneq (, $(findstring iOS, $(SYS))) ++ # Do iOS things ++ CFLAGS = -fPIC ++ LDFLAGS = -fPIC -ldl ++endif ++ ++#custom config ++ifeq (.config, $(wildcard .config)) ++ include .config ++endif ++ ++LIBNAME= $T.so.$V ++ ++CFLAGS += $(OPENSSL_CFLAGS) $(LUA_CFLAGS) $(TARGET_FLAGS) ++LDFLAGS += -shared $(OPENSSL_LIBS) $(LUA_LIBS) ++# Compilation directives ++WARN_MIN = -Wall -Wno-unused-value ++WARN = -Wall ++WARN_MOST = $(WARN) -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -pedantic ++CFLAGS += -g $(WARN_MIN) -DPTHREADS -Ideps -Ideps/lua-compat -Ideps/auxiliar ++ ++ ++OBJS=src/asn1.o deps/auxiliar/auxiliar.o src/bio.o src/cipher.o src/cms.o src/compat.o src/crl.o src/csr.o src/dh.o src/digest.o src/dsa.o \ ++src/ec.o src/engine.o src/hmac.o src/lbn.o src/lhash.o src/misc.o src/ocsp.o src/openssl.o src/ots.o src/pkcs12.o src/pkcs7.o \ ++src/pkey.o src/rsa.o src/ssl.o src/th-lock.o src/util.o src/x509.o src/xattrs.o src/xexts.o src/xname.o src/xstore.o \ ++src/xalgor.o src/callback.o src/srp.o deps/auxiliar/subsidiar.o ++ ++.c.o: ++ $(CC) $(CFLAGS) -c -o $@ $? ++ ++all: $T.so ++ @echo "Target system: "$(SYS) ++ ++$T.so: lib$T.a ++ $(CC) -o $@ src/openssl.o -L. -l$T $(LDFLAGS) ++ ++lib$T.a: $(OBJS) ++ $(AR) rcs $@ $? ++ ++install: all ++ mkdir -p $(LUA_LIBDIR) ++ cp $T.so $(LUA_LIBDIR) ++ ++info: ++ @echo "Target system: "$(SYS) ++ @echo "CC:" $(CC) ++ @echo "AR:" $(AR) ++ @echo "PREFIX:" $(PREFIX) ++ ++clean: ++ rm -f $T.so lib$T.a $(OBJS) ++ ++# vim: ts=8 sw=8 noet +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/Makefile.win luvi-src-v2.7.6/deps/lua-openssl/Makefile.win +--- luvi-src-v2.7.6.orig/deps/lua-openssl/Makefile.win 2019-02-13 11:31:40.277302045 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/Makefile.win 2019-02-13 11:53:24.105128513 +0100 +@@ -1,25 +1,31 @@ +-T= openssl +- +-include config.win +- +-OBJS=src\asn1.obj src\auxiliar.obj src\bio.obj src\cipher.obj src\cms.obj src\compat.obj src\crl.obj src\csr.obj src\dh.obj src\digest.obj src\dsa.obj \ +-src\ec.obj src\engine.obj src\hmac.obj src\lbn.obj src\lhash.obj src\misc.obj src\ocsp.obj src\openssl.obj src\ots.obj src\pkcs12.obj src\pkcs7.obj \ +-src\pkey.obj src\rsa.obj src\ssl.obj src\th-lock.obj src\util.obj src\x509.obj src\xattrs.obj src\xexts.obj src\xname.obj src\xstore.obj src\xalgor.obj src\callback.obj +- +- +-lib: src\$T.dll +- +-.c.obj: +- $(CC) /nologo /c /DLUA_BUILD_AS_DLL /DLUA_LIB /Fo$@ $(CFLAGS) $< +- +-src\$T.dll: $(OBJS) +- link /DLL /out:src\$T.dll $(OBJS) "$(LUA_LIB)" "$(OPENSSL_LIB)" ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib +- IF EXIST src\$T.dll.manifest mt -manifest src\$T.dll.manifest -outputresource:src\$T.dll;2 +- +-install: src\$T.dll +- IF NOT EXIST "$(LUA_LIBDIR)" mkdir "$(LUA_LIBDIR)" +- copy src\$T.dll "$(LUA_LIBDIR)" +- +-clean: +- del src\$T.dll $(OBJS) src\$T.lib src\$T.exp +- IF EXIST src\$T.dll.manifest del src\$T.dll.manifest +\ No newline at end of file ++T= openssl ++ ++include config.win ++ ++OBJS= \ ++deps\auxiliar\auxiliar.obj src\asn1.obj src\bio.obj src\cipher.obj src\cms.obj \ ++src\compat.obj src\crl.obj src\csr.obj src\dh.obj src\digest.obj src\dsa.obj \ ++src\ec.obj src\engine.obj src\hmac.obj src\lbn.obj src\lhash.obj src\misc.obj \ ++src\ocsp.obj src\openssl.obj src\ots.obj src\pkcs12.obj src\pkcs7.obj \ ++src\pkey.obj src\rsa.obj src\ssl.obj src\th-lock.obj src\util.obj src\x509.obj \ ++src\xattrs.obj src\xexts.obj src\xname.obj src\xstore.obj src\xalgor.obj \ ++src\callback.obj src\srp.obj deps\auxiliar\subsidiar.obj ++ ++ ++lib: src\$T.dll ++ ++.c.obj: ++ $(CC) /nologo /c /I"deps/lua-compat" /I"deps/auxiliar" /DLUA_BUILD_AS_DLL /DLUA_LIB /Fo$@ $(CFLAGS) $< ++ ++src\$T.dll: $(OBJS) ++ link /DLL /out:src\$T.dll $(OBJS) "$(LUA_LIB)" "$(OPENSSL_LIB)" \ ++ ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ++ IF EXIST src\$T.dll.manifest mt -manifest src\$T.dll.manifest -outputresource:src\$T.dll;2 ++ ++install: src\$T.dll ++ IF NOT EXIST "$(LUA_LIBDIR)" mkdir "$(LUA_LIBDIR)" ++ copy src\$T.dll "$(LUA_LIBDIR)" ++ ++clean: ++ del src\$T.dll $(OBJS) src\$T.lib src\$T.exp ++ IF EXIST src\$T.dll.manifest del src\$T.dll.manifest +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/openssl-scm-6.rockspec luvi-src-v2.7.6/deps/lua-openssl/openssl-scm-6.rockspec +--- luvi-src-v2.7.6.orig/deps/lua-openssl/openssl-scm-6.rockspec 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/openssl-scm-6.rockspec 2019-02-13 11:53:24.105128513 +0100 +@@ -0,0 +1,80 @@ ++package = "openssl" ++version = "scm-6" ++ ++source = { ++ url = "gitrec://github.com/zhaozg/lua-openssl", ++ tag = "0.7.4" ++} ++ ++description = { ++ summary = "Openssl binding for Lua", ++ homepage = "https://github.com/zhaozg/lua-openssl", ++ license = "MIT", ++ maintainer = "George Zhao", ++ detailed = [[ ++ ]], ++} ++ ++dependencies = { ++ "luarocks-fetch-gitrec", ++ "lua >= 5.1, < 5.4" ++} ++ ++external_dependencies = { ++ OPENSSL = { ++ header = "openssl/evp.h" ++ } ++} ++ ++build = { ++ type = "builtin", ++ ++ modules = { ++ openssl = { ++ sources = { ++ "deps/auxiliar/auxiliar.c","src/asn1.c","src/bio.c","src/callback.c", ++ "src/cipher.c","src/cms.c","src/compat.c","src/crl.c", ++ "src/csr.c","src/dh.c","src/digest.c","src/dsa.c", ++ "src/ec.c","src/engine.c","src/hmac.c","src/lbn.c", ++ "src/lhash.c","src/misc.c","src/ocsp.c","src/openssl.c", ++ "src/ots.c","src/pkcs7.c","src/pkcs12.c","src/pkey.c", ++ "src/rsa.c","src/ssl.c","src/th-lock.c","src/util.c", ++ "src/x509.c","src/xattrs.c","src/xexts.c","src/xname.c", ++ "src/xalgor.c","src/xstore.c", "src/srp.c", ++ "deps/auxiliar/subsidiar.c" ++ }, ++ incdirs = {"$(OPENSSL_DIR)/include", "deps/auxiliar", "deps/lua-compat"}, ++ defines = {"PTHREADS"}, ++ libraries = {"ssl", "crypto"}, ++ } ++ }, ++ ++ platforms = { ++ windows = { ++ modules = { ++ openssl = { ++ libraries = {"libeay32", "ssleay32", "ws2_32", "kernel32", "user32", "gdi32", "advapi32"}, ++ defines = {"LUA_BUILD_AS_DLL", "LUA_LIB", "WIN32_LEAN_AND_MEAN"}, ++ incdirs = {"$(OPENSSL_DIR)/include"}, ++ libdirs = {"$(OPENSSL_DIR)/lib"}, ++ } ++ } ++ }, ++ linux = { ++ modules = { ++ openssl = { ++ incdirs = {"$(OPENSSL_DIR)/include"}, ++ libdirs = {"$(OPENSSL_DIR)/lib"}, ++ } ++ } ++ }, ++ macosx = { ++ modules = { ++ openssl = { ++ incdirs = {"$(OPENSSL_DIR)/include"}, ++ libdirs = {"$(OPENSSL_DIR)/lib"}, ++ } ++ } ++ } ++ }, ++} +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/README.md luvi-src-v2.7.6/deps/lua-openssl/README.md +--- luvi-src-v2.7.6.orig/deps/lua-openssl/README.md 2019-02-13 11:31:40.273968734 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/README.md 2019-02-13 11:53:24.105128513 +0100 +@@ -3,12 +3,12 @@ lua-openssl toolkit - A free, MIT-licens + [![Build Status](https://travis-ci.org/zhaozg/lua-openssl.svg)](https://travis-ci.org/zhaozg/lua-openssl) + [![Build status](https://ci.appveyor.com/api/projects/status/f8xchhlj035yqq88/branch/master?svg=true)](https://ci.appveyor.com/project/zhaozg/lua-openssl/branch/master) + +-#Index ++# Index + + 1. [Introduction](#introduction) + 2. [Documentation](#documentation) +-2. [Howto](#a---howto) +-3. [Examples](#b--example-usage) ++2. [Howto](#howto) ++3. [Examples](#example-usage) + + # Introduction + +@@ -16,17 +16,17 @@ I needed a full OpenSSL binding for Lua, + I found the PHP openssl binding is a good implementation, and it inspired me. + So I decided to write this OpenSSL toolkit for Lua. + +-The goal is to fully support the listed items.Below you can find the development progress of lua-openssl. ++The goal is to fully support the listed items. Below you can find the development progress of lua-openssl: + + * Symmetrical encrypt/decrypt. (Finished) + * Message digest. (Finished) + * Asymmetrical encrypt/decrypt/sign/verify/seal/open. (Finished) + * X509 certificate. (Finished) +-* PKCS7/CMS. (Developing) ++* PKCS7/CMS. (Finished) + * SSL/TLS. (Finished) + +-Most of the lua-openssl functions require a key or certificate as argument; to make things easy to use OpenSSL, +-This rule allow you to specify certificates or keys in the following ways: ++Most of the lua-openssl functions require a key or certificate as argument; to make things easy to use OpenSSL. ++This rule allows you to specify certificates or keys in the following ways: + + 1. As an openssl.x509 object returned from openssl.x509.read + 2. As an openssl.evp_pkey object return from openssl.pkey.read or openssl.pkey.new +@@ -47,7 +47,7 @@ digest() equals with digest.digest(), sa + + ## documentation + +-Document please see [here](http://zhaozg.github.io/lua-openssl/) ++Document please see [here](http://zhaozg.github.io/lua-openssl/index.html) + + ## compat with others + +@@ -101,26 +101,26 @@ below. + + bn library: + ``` +- __add(x,y) compare(x,y) pow(x,y) +- __div(x,y) div(x,y) powmod(x,y,m) +- __eq(x,y) divmod(x,y) random(bits) +- __lt(x,y) gcd(x,y) rmod(x,y) +- __mod(x,y) invmod(x) sqr(x) +- __mul(x,y) isneg(x) sqrmod(x) +- __pow(x,y) isodd(x) sqrtmod(x) +- __sub(x,y) isone(x) sub(x,y) +- __tostring(x) isprime(x,[checks]) submod(x,y,m) +- __unm(x) iszero(x) text(t) +- abs(x) mod(x,y) tohex(x) +- add(x,y) mul(x,y) tonumber(x) +- addmod(x,y,m) mulmod(x,y,m) tostring(x) +- aprime(bits) neg(x) totext(x) +- bits(x) number(x) version ++ __add(x,y) compare(x,y) pow(x,y) ++ __div(x,y) div(x,y) powmod(x,y,m) ++ __eq(x,y) divmod(x,y) random(bits) ++ __lt(x,y) gcd(x,y) rmod(x,y) ++ __mod(x,y) invmod(x) sqr(x) ++ __mul(x,y) isneg(x) sqrmod(x) ++ __pow(x,y) isodd(x) sqrtmod(x) ++ __sub(x,y) isone(x) sub(x,y) ++ __tostring(x) isprime(x,[checks]) submod(x,y,m) ++ __unm(x) iszero(x) text(t) ++ abs(x) mod(x,y) tohex(x) ++ add(x,y) mul(x,y) tonumber(x) ++ addmod(x,y,m) mulmod(x,y,m) tostring(x) ++ aprime(bits) neg(x) totext(x) ++ bits(x) number(x) version + ``` + + ## Version + +-This lua-openssl toolkit works with Lua 5.1 or 5.2, and OpenSSL (0.9.8 or above 1.0.0). ++This lua-openssl toolkit works with Lua 5.1/5.2 or LuaJIT 2.0/2.1, and OpenSSL (0.9.8 or above 1.0.0). + It is recommended to use the most up-to-date OpenSSL version because of the recent security fixes. + + If you want to get the lua-openssl and OpenSSL versions from a Lua script, here is how: +@@ -129,15 +129,20 @@ If you want to get the lua-openssl and O + openssl = require "openssl" + lua_openssl_version, lua_version, openssl_version = openssl.version() + ``` ++## Style ++ ++Source code of lua-openssl tidy with [astyle](http://astyle.sourceforge.net/) `--style=allman --indent=spaces=2` + + ## Bugs + +-Lua-Openssl is heavily updated, if you find bug, please report to [here](https://github.com/zhaozg/lua-openssl/issues/) ++Lua-Openssl is heavily updated, if you find a bug, please report to [here](https://github.com/zhaozg/lua-openssl/issues/) + +-#A. Howto ++# Howto + + ### Howto 1: Build on Linux/Unix System. + ++ git clone --recurse https://github.com/zhaozg/lua-openssl.git lua-openssl ++ cd lua-openssl + make + make install + make clean +@@ -147,6 +152,8 @@ Lua-Openssl is heavily updated, if you f + Before building, please change the setting in the config.win file. + Works with Lua5.1 (should support Lua5.2 by updating the config.win file). + ++ git clone --recurse https://github.com/zhaozg/lua-openssl.git lua-openssl ++ cd lua-openssl + nmake -f makefile.win + nmake -f makefile.win install + nmake -f makefile.win clean +@@ -154,6 +161,8 @@ Works with Lua5.1 (should support Lua5.2 + + ### Howto 3: Build on Windows with mingw. + ++ git clone --recurse https://github.com/zhaozg/lua-openssl.git lua-openssl ++ cd lua-openssl + make + make install + make clean +@@ -170,17 +179,17 @@ _code_ can pass to openssl.error() to ge + + All SSL object IO operation methods return nil or false when fail or error. + When nil returned, it followed by 'ssl' or 'syscall', means SSL layer or +-system layer error. When false returned, it followed by number 0, 'want_read', +-'want_write','want_x509_lookup','want_connect','want_accept'. Numnber 0 means +-SSL connection closed, others means you should do some SSL operation. ++system layer error. When false returned, it is followed by number 0, 'want_read', ++'want_write','want_x509_lookup','want_connect','want_accept'. Number 0 means ++SSL connection closed, other numbers means you should do some SSL operation. + +- Please remeber that when lua-openssl function or methods failed without +-error code, you can get last error by openssl.error(), and repeat call ++ Please remember that when lua-openssl function or methods fail without an ++error code, you can get the last error by openssl.error(), and repeat call + openssl.error() will walk through error stacks of current threads. + openssl.error(true) will also clear error stacks after get last error code, + this is very useful to free memory when lua-openssl repeat calls or run long times. + +-#B. Example usage ++# Example usage + + ### Example 1: short encrypt/decrypt + +@@ -206,7 +215,20 @@ bb = mdc:final() + assert(openssl.hex(aa,true)==bb) + ``` + +-### Example 3: Iterate a openssl.stack_of_x509(sk_x509) object ++### Example 3: Quick HMAC hash ++ ++```lua ++local hmac = require "openssl".hmac ++ ++alg = 'sha256' ++key = '0123456789' ++msg = 'example message' ++ ++hmac.hmac(alg, msg, key, true) -- binary/"raw" output ++hmac.hmac(alg, msg, key, false) -- hex output ++``` ++ ++### Example 4: Iterate a openssl.stack_of_x509(sk_x509) object + + ```lua + n = #sk +@@ -215,7 +237,7 @@ for i=1, n do + end + ``` + +-### Example 4: read and parse certificate ++### Example 5: read and parse certificate + + ```lua + local openssl = require('openssl') +@@ -243,10 +265,10 @@ end + test_x509() + ``` + +-###Example 5: bio network handle(TCP) ++### Example 5: bio network handle(TCP) + + * server +- ++ + ```lua + local openssl = require'openssl' + local bio = openssl.bio +@@ -270,6 +292,7 @@ end + ``` + + * client ++ + ```lua + local openssl = require'openssl' + local bio = openssl.bio +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/rockspecs/openssl-scm-0.rockspec luvi-src-v2.7.6/deps/lua-openssl/rockspecs/openssl-scm-0.rockspec +--- luvi-src-v2.7.6.orig/deps/lua-openssl/rockspecs/openssl-scm-0.rockspec 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/rockspecs/openssl-scm-0.rockspec 1970-01-01 01:00:00.000000000 +0100 +@@ -1,40 +0,0 @@ +-package = "openssl" +-version = "scm-0" +- +-source = { +- url = "https://github.com/zhaozg/lua-openssl/archive/master.zip", +- dir = "lua-openssl-master", +-} +- +-description = { +- summary = "Openssl binding for Lua", +- homepage = "https://github.com/zhaozg/lua-openssl", +- license = "MIT/X11", +- maintainer = "George Zhao", +- detailed = [[ +- ]], +-} +- +-dependencies = { +- "lua >= 5.1, < 5.3" +-} +- +-external_dependencies = { +-} +- +-build = { +- type = "builtin", +- +- platforms = { +- windows = { +- type = "command", +- build_command = [[nmake -f makefile.win]], +- install_command = [[nmake -f makefile.win install]] +- }, +- unix = { +- type = "command", +- build_command = [[make]], +- install_command = [[make install]] +- } +- } +-} +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/rockspecs/openssl-scm-1.rockspec luvi-src-v2.7.6/deps/lua-openssl/rockspecs/openssl-scm-1.rockspec +--- luvi-src-v2.7.6.orig/deps/lua-openssl/rockspecs/openssl-scm-1.rockspec 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/rockspecs/openssl-scm-1.rockspec 1970-01-01 01:00:00.000000000 +0100 +@@ -1,61 +0,0 @@ +-package = "openssl" +-version = "scm-1" +- +-source = { +- url = "https://github.com/zhaozg/lua-openssl/archive/master.zip", +- dir = "lua-openssl-master", +-} +- +-description = { +- summary = "Openssl binding for Lua", +- homepage = "https://github.com/zhaozg/lua-openssl", +- license = "MIT/X11", +- maintainer = "George Zhao", +- detailed = [[ +- ]], +-} +- +-dependencies = { +- "lua >= 5.1, < 5.4" +-} +- +-external_dependencies = { +- OPENSSL = { +- header = "openssl/evp.h" +- } +-} +- +-build = { +- type = "builtin", +- +- modules = { +- openssl = { +- sources = { +- "src/asn1.c","src/auxiliar.c","src/bio.c","src/callback.c", +- "src/cipher.c","src/cms.c","src/compat.c","src/crl.c", +- "src/csr.c","src/dh.c","src/digest.c","src/dsa.c", +- "src/ec.c","src/engine.c","src/hmac.c","src/lbn.c", +- "src/lhash.c","src/misc.c","src/ocsp.c","src/openssl.c", +- "src/ots.c","src/pkcs7.c","src/pkcs12.c","src/pkey.c", +- "src/rsa.c","src/ssl.c","src/th-lock.c","src/util.c", +- "src/x509.c","src/xattrs.c","src/xexts.c","src/xname.c", +- "src/xalgor.c","src/xstore.c", +- }, +- incdirs = {"$(OPENSSL_INCDIR)", "deps"}, +- libdirs = {"$(OPENSSL_LIBDIR)"}, +- defines = {"PTHREADS"}, +- libraries = {"ssl", "crypto"}, +- } +- }, +- +- platforms = { +- windows = { +- modules = { +- openssl = { +- libraries = {"libeay32", "ssleay32", "ws2_32", "kernel32", "user32", "gdi32", "advapi32"}, +- defines = {"LUA_BUILD_AS_DLL", "LUA_LIB", "WIN32_LEAN_AND_MEAN"}, +- } +- } +- } +- }, +-} +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/samples/srp.lua luvi-src-v2.7.6/deps/lua-openssl/samples/srp.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/samples/srp.lua 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/samples/srp.lua 2019-02-13 11:53:24.275126573 +0100 +@@ -0,0 +1,43 @@ ++local openssl = require'openssl' ++local srp = assert(openssl.srp) ++ ++--both ++local GN = srp.get_default_gN('1024'); ++ ++local function test(username, clipass, srvpass) ++ assert(username) ++ assert(clipass) ++ srvpass = srvpass or clipass ++ --server ++ local salt, v = GN:create_verifier(username,srvpass) ++ print('salt:', salt:tohex()) ++ print('verifier:',v:tohex()) ++ ++ local Bpub, Brnd = GN:calc_b(v) ++ print("Bpnb:",Bpub:tohex()) ++ print("Brnd:",Brnd:tohex()) ++ ++ --client ++ local Apub, Arnd = GN:calc_a() ++ print("Apnb:",Apub:tohex()) ++ print("Arnd:",Arnd:tohex()) ++ ++ --both ++ local u = GN:calc_u(Apub, Bpub) ++ print("u:",u:tohex()) ++ ++ --client ++ local x = GN.calc_x(salt, username, clipass) ++ local Kclient = GN:calc_client_key(Bpub,x, Arnd, u) ++ ++ --server ++ local Kserver = GN:calc_server_key(Apub, v, u, Brnd) ++ ++ return Kclient==Kserver ++end ++ ++local cnt = 1 ++for i=1,cnt do ++assert(test('zhaozg','password','password')) ++assert(not test('zhaozg','password','password1')) ++end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/asn1.c luvi-src-v2.7.6/deps/lua-openssl/src/asn1.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/asn1.c 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/asn1.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,9 +1,13 @@ +-/*=========================================================================*\ +-* asn1.c +-* asn1 routines for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++openssl.asn1 module for lua-openssl binding. ++Provide asn1\_object, asn1\_string, asn1\_object as lua object. ++Sometime when you want to custome x509, you maybe need to use this. ++ ++@module asn1 ++@usage ++ asn1 = require('openssl').asn1 ++*/ ++ + #include "openssl.h" + #include "private.h" + #include +@@ -15,7 +19,7 @@ + #define timezone _timezone + #endif + +-static LuaL_Enum asn1_const[] = ++static LuaL_Enumeration asn1_const[] = + { + /* 0 */ + {"UNIVERSAL", V_ASN1_UNIVERSAL}, +@@ -75,10 +79,14 @@ static LuaL_Enum asn1_const[] = + #define TAG_IDX_OFFSET 11 + #define TAG_IDX_LENGTH 31 + +- ++/*** ++create asn1_type object ++@function new_type ++*/ + static int openssl_asn1type_new(lua_State*L) + { + ASN1_TYPE* at = ASN1_TYPE_new(); ++ ASN1_STRING *s = NULL; + int ret = 1; + if (lua_isboolean(L, 1)) + { +@@ -99,9 +107,8 @@ static int openssl_asn1type_new(lua_Stat + const char* octet = luaL_checklstring(L, 1, &size); + ret = ASN1_TYPE_set_octetstring(at, (unsigned char*)octet, size); + } +- else if (auxiliar_isgroup(L, "openssl.asn1group", 1)) ++ else if ((s = GET_GROUP(1, ASN1_STRING, "openssl.asn1group")) != NULL) + { +- ASN1_STRING* s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); + ret = ASN1_TYPE_set1(at, ASN1_STRING_type(s), s); + } + else +@@ -115,6 +122,436 @@ static int openssl_asn1type_new(lua_Stat + return 1; + } + ++/*** ++parse der encoded string ++@function get_object ++@tparam string der string ++@tparam[opt=1] number start offset to parse ++@tparam[opt=-i] number stop offset to parse ++ this like string.sub() ++@treturn[1] number tag ++@treturn[1] number class ++@treturn[1] number parsed data start offset ++@treturn[1] number parsed data stop offset ++@treturn[1] boolean true for constructed data ++@treturn[2] nil for fail ++@treturn[2] string error msg ++@treturn[2] number inner error code ++*/ ++static int openssl_get_object(lua_State*L) ++{ ++ size_t l = 0; ++ const char* asn1s = luaL_checklstring(L, 1, &l); ++ size_t off = posrelat(luaL_optinteger(L, 2, 1), l); ++ size_t length = posrelat(luaL_optinteger(L, 3, l), l); ++ ++ const unsigned char *p = (const unsigned char *)asn1s + off - 1; ++ long len = 0; ++ int tag = 0; ++ int class = 0; ++ int ret; ++ ++ p = (const unsigned char *)asn1s + off - 1; ++ ret = ASN1_get_object(&p, &len, &tag, &class, length - off + 1); ++ if (ret & 0x80) ++ { ++ lua_pushnil(L); ++ lua_pushstring(L, "arg 1 with error encoding"); ++ lua_pushinteger(L, ret); ++ return 3; ++ } ++ lua_pushinteger(L, tag); ++ lua_pushinteger(L, class); ++ lua_pushinteger(L, p - (const unsigned char *)asn1s + 1); ++ lua_pushinteger(L, p + len - (const unsigned char *)asn1s); ++ ++ lua_pushboolean(L, ret & V_ASN1_CONSTRUCTED); ++ return 5; ++} ++ ++/*** ++do der encode and return encoded string partly head or full ++@function put_object ++@tparam number tag ++@tparam number class ++@tparam[opt=nil] number|string length or date to encode, defualt will make ++indefinite length constructed ++@tparam[opt=nil] boolean constructed or not ++@treturn string der encoded string or head when not give data ++*/ ++static int openssl_put_object(lua_State*L) ++{ ++ int tag = luaL_checkint(L, 1); ++ int cls = luaL_checkint(L, 2); ++ int length = 0; ++ int constructed; ++ unsigned char *p1, *p2; ++ const char* dat = NULL; ++ luaL_Buffer B; ++ ++ luaL_argcheck(L, ++ lua_isnoneornil(L, 3) || lua_type(L, 3) == LUA_TNUMBER || lua_isstring(L, 3), 3, ++ "if exist only accept string or number"); ++ luaL_argcheck(L, lua_isnoneornil(L, 4) || lua_isboolean(L, 4), 4, ++ "if exist must be boolean type"); ++ ++ if (lua_isnoneornil(L, 3)) ++ { ++ /* constructed == 2 for indefinite length constructed */ ++ constructed = 2; ++ length = 0; ++ } ++ else ++ { ++ if (lua_type(L, 3) == LUA_TNUMBER) ++ { ++ length = lua_tointeger(L, 3); ++ } ++ else if (lua_isstring(L, 3)) ++ { ++ size_t l; ++ dat = lua_tolstring(L, 3, &l); ++ length = (int)l; ++ } ++ ++ constructed = lua_isnoneornil(L, 4) ? 0 : lua_toboolean(L, 4); ++ } ++ luaL_buffinit(L, &B); ++ p1 = (unsigned char *)luaL_prepbuffer(&B); ++ p2 = p1; ++ ++ ASN1_put_object(&p2, constructed, length, tag, cls); ++ luaL_addsize(&B, p2 - p1); ++ if (dat) ++ { ++ luaL_addlstring(&B, dat, length); ++ } ++ luaL_pushresult(&B); ++ return 1; ++}; ++ ++/*** ++make tag, class number to string ++ ++@function tostring ++@tparam number clsortag which to string ++@tparam string range only accept 'class' or 'tag' ++*/ ++static int openssl_asn1_tostring(lua_State*L) ++{ ++ int val = luaL_checkint(L, 1); ++ const char* range = luaL_optstring(L, 2, NULL); ++ int i; ++ ++ if (range == NULL) ++ { ++ for (i = 0; i < sizeof(asn1_const) / sizeof(LuaL_Enumeration) - 1; i++) ++ { ++ if (asn1_const[i].val == val) ++ { ++ lua_pushstring(L, asn1_const[i + CLS_IDX_OFFSET].name); ++ return 1; ++ } ++ } ++ } ++ else if (strcmp("tag", range) == 0) ++ { ++ for (i = 0; i < TAG_IDX_LENGTH; i++) ++ { ++ if (asn1_const[i + TAG_IDX_OFFSET].val == val) ++ { ++ lua_pushstring(L, asn1_const[i + TAG_IDX_OFFSET].name); ++ return 1; ++ } ++ } ++ } ++ else if (strcmp("class", range) == 0) ++ { ++ for (i = 0; i < CLS_IDX_LENGTH; i++) ++ { ++ if (asn1_const[i + CLS_IDX_OFFSET].val == val) ++ { ++ lua_pushstring(L, asn1_const[i + CLS_IDX_OFFSET].name); ++ return 1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++/*** ++Create asn1_string object ++ ++

asn1_string object support types: "integer", "enumerated", "bit", "octet", "utf8", ++"numeric", "printable", "t61", "teletex", "videotex", "ia5", "graphics", "iso64", ++"visible", "general", "unversal", "bmp", "utctime"

++ ++@function new_string ++@tparam string data to create new asn1_string ++@tparam[opt] string type asn1 string type, defult with 'utf8' ++@treturn asn1_string ++@see asn1_string ++*/ ++static int openssl_asn1string_new(lua_State* L) ++{ ++ size_t size = 0; ++ const char* data = luaL_checklstring(L, 1, &size); ++ int type = luaL_checkint(L, 2); ++ ASN1_STRING *s = ASN1_STRING_type_new(type); ++ ASN1_STRING_set(s, data, size); ++ PUSH_OBJECT(s, "openssl.asn1_string"); ++ return 1; ++} ++ ++/*** ++Create asn1_integer object ++ ++@function new_integer ++@tparam number|bn integer to create new asn1_integer ++@treturn asn1_integer ++@see asn1_integer ++*/ ++static int openssl_asn1int_new(lua_State* L) ++{ ++ ASN1_INTEGER *ai = ASN1_INTEGER_new(); ++ if (lua_isinteger(L, 1)) ++ { ++ long v = luaL_checklong(L, 1); ++ ASN1_INTEGER_set(ai, v); ++ } ++ else if (!lua_isnone(L, 1)) ++ { ++ BIGNUM *bn = BN_get(L, 1); ++ ai = BN_to_ASN1_INTEGER(bn, ai); ++ BN_free(bn); ++ } ++ PUSH_OBJECT(ai, "openssl.asn1_integer"); ++ return 1; ++} ++ ++/*** ++Create asn1_time object ++@function new_generalizedtime ++@tparam none|number|string time ++@treturn asn1_time ++*/ ++static int openssl_asn1generalizedtime_new(lua_State* L) ++{ ++ ASN1_GENERALIZEDTIME* a = NULL; ++ int ret = 1; ++ luaL_argcheck(L, ++ 1, ++ lua_isnone(L, 1) || lua_isnumber(L, 1) || lua_isstring(L, 1), ++ "must be number, string or none" ++ ); ++ a = ASN1_GENERALIZEDTIME_new(); ++ if (lua_isnumber(L, 1)) ++ ASN1_GENERALIZEDTIME_set(a, luaL_checkinteger(L, 1)); ++ else if (lua_isstring(L, 1)) ++ ret = ASN1_GENERALIZEDTIME_set_string(a, lua_tostring(L, 1)); ++ ++ if (ret == 1) ++ PUSH_OBJECT(a, "openssl.asn1_time"); ++ else ++ return openssl_pushresult(L, ret); ++ return 1; ++} ++ ++/*** ++Create asn1_time object ++@function new_utctime ++@tparam none|number|string time ++@treturn asn1_time ++*/ ++static int openssl_asn1utctime_new(lua_State* L) ++{ ++ ASN1_UTCTIME* a = NULL; ++ int ret = 1; ++ luaL_argcheck(L, ++ 1, ++ lua_isnone(L, 1) || lua_isnumber(L, 1) || lua_isstring(L, 1), ++ "must be number, string or none" ++ ); ++ a = ASN1_UTCTIME_new(); ++ if (lua_isnumber(L, 1)) ++ { ++ time_t t = luaL_checkinteger(L, 1); ++ ASN1_TIME_set(a, t); ++ } ++ else if (lua_isstring(L, 1)) ++ ret = ASN1_TIME_set_string(a, lua_tostring(L, 1)); ++ ++ if (ret == 1) ++ PUSH_OBJECT(a, "openssl.asn1_time"); ++ else ++ return openssl_pushresult(L, ret); ++ return 1; ++} ++ ++/*** ++get nid for txt, which can be short name, long name, or numerical oid ++ ++@function txt2nid ++@tparam string txt which get to nid ++@treturn integer nid or nil on fail ++*/ ++static int openssl_txt2nid(lua_State*L) ++{ ++ const char* txt = luaL_checkstring(L, 1); ++ int nid = OBJ_txt2nid(txt); ++ if (nid != NID_undef) ++ { ++ lua_pushinteger(L, nid); ++ } ++ else ++ lua_pushnil(L); ++ ++ return 1; ++} ++ ++/*** ++Create asn1_object object ++ ++@function new_object ++@tparam string name_or_oid short name,long name or oid string ++@tparam[opt] boolean no_name true for only oid string, default is false ++@treturn asn1_object mapping to ASN1_OBJECT in openssl ++@see asn1_object ++*/ ++ ++/*** ++Create asn1_object object ++ ++@function new_object ++@tparam integer nid ident to asn1_object ++@treturn asn1_object mapping to ASN1_OBJECT in openssl ++@see asn1_object ++*/ ++ ++/*** ++Create asn1_object object ++ ++@function new_object ++@tparam table options have sn, ln, oid keys to create asn1_object ++@treturn asn1_object mapping to ASN1_OBJECT in openssl ++@see asn1_object ++*/ ++static int openssl_asn1object_new(lua_State* L) ++{ ++ if (lua_type(L, 1) == LUA_TNUMBER) ++ { ++ int nid = luaL_checkint(L, 1); ++ ASN1_OBJECT* obj = OBJ_nid2obj(nid); ++ if (obj) ++ PUSH_OBJECT(obj, "openssl.asn1_object"); ++ else ++ lua_pushnil(L); ++ } ++ else if (lua_isstring(L, 1)) ++ { ++ const char* txt = luaL_checkstring(L, 1); ++ int no_name = lua_isnone(L, 2) ? 0 : lua_toboolean(L, 2); ++ ++ ASN1_OBJECT* obj = OBJ_txt2obj(txt, no_name); ++ if (obj) ++ PUSH_OBJECT(obj, "openssl.asn1_object"); ++ else ++ lua_pushnil(L); ++ } ++ else if (lua_istable(L, 1)) ++ { ++ const char *oid, *sn, *ln; ++ ASN1_OBJECT* obj; ++ int nid; ++ ++ lua_getfield(L, 1, "oid"); ++ luaL_argcheck(L, lua_isstring(L, -1), 1, "not have oid field or is not string"); ++ oid = luaL_checkstring(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "sn"); ++ luaL_argcheck(L, lua_isstring(L, -1), 1, "not have sn field or is not string"); ++ sn = luaL_checkstring(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "ln"); ++ luaL_argcheck(L, lua_isstring(L, -1), 1, "not have ln field or is not string"); ++ ln = luaL_checkstring(L, -1); ++ lua_pop(L, 1); ++ ++ if (OBJ_txt2nid(oid) != NID_undef) ++ { ++ luaL_argerror(L, 1, "oid already exist"); ++ } ++ ++ if (OBJ_sn2nid(sn) != NID_undef) ++ { ++ luaL_argerror(L, 1, "sn already exist"); ++ } ++ ++ if (OBJ_ln2nid(ln) != NID_undef) ++ { ++ luaL_argerror(L, 1, "ln already exist"); ++ } ++ ++ nid = OBJ_create(oid, sn, ln); ++ if (nid != NID_undef) ++ { ++ obj = OBJ_nid2obj(nid); ++ PUSH_OBJECT(obj, "openssl.asn1_object"); ++ } ++ else ++ luaL_argerror(L, 1, "create object fail"); ++ } ++ else ++ luaL_argerror(L, 1, "need accept paramater"); ++ ++ return 1; ++} ++ ++/*** ++convert der encoded asn1type string to object ++@function asn1type_di2 ++@tparam string der ++@treturn asn1type object for success, and nil for fail ++*/ ++static int openssl_asn1type_d2i(lua_State*L) ++{ ++ size_t size; ++ const unsigned char* data = (const unsigned char*)luaL_checklstring(L, 1, &size); ++ ASN1_TYPE* at = d2i_ASN1_TYPE(NULL, &data, size); ++ if (at) ++ { ++ PUSH_OBJECT(at, "openssl.asn1_type"); ++ } ++ else ++ lua_pushnil(L); ++ return 1; ++} ++ ++static luaL_Reg R[] = ++{ ++ {"new_object", openssl_asn1object_new}, ++ ++ {"new_integer", openssl_asn1int_new}, ++ {"new_string", openssl_asn1string_new}, ++ {"new_utctime", openssl_asn1utctime_new}, ++ {"new_generalizedtime", openssl_asn1generalizedtime_new}, ++ ++ {"new_type", openssl_asn1type_new}, ++ {"d2i_asn1type", openssl_asn1type_d2i}, ++ ++ {"get_object", openssl_get_object}, ++ {"put_object", openssl_put_object}, ++ ++ {"tostring", openssl_asn1_tostring}, ++ {"txt2nid", openssl_txt2nid}, ++ ++ {NULL, NULL} ++}; ++ ++ + static int openssl_asn1type_type(lua_State*L) + { + ASN1_TYPE* at = CHECK_OBJECT(1, ASN1_TYPE, "openssl.asn1_type"); +@@ -289,20 +726,6 @@ int openssl_push_asn1type(lua_State* L, + return 1; + } + +-static int openssl_asn1type_d2i(lua_State*L) +-{ +- size_t size; +- const unsigned char* data = (const unsigned char*)luaL_checklstring(L, 1, &size); +- ASN1_TYPE* at = d2i_ASN1_TYPE(NULL, &data, size); +- if (at) +- { +- PUSH_OBJECT(at, "openssl.asn1_type"); +- } +- else +- lua_pushnil(L); +- return 1; +-} +- + static luaL_Reg asn1type_funcs[] = + { + {"type", openssl_asn1type_type}, +@@ -320,23 +743,44 @@ static luaL_Reg asn1type_funcs[] = + {NULL, NULL} + }; + +- +-/*** asn1_object routines ***/ ++/*** ++openssl.asn1_object object ++@type asn1_object ++*/ ++/*** ++get nid of asn1_object. ++ ++@function nid ++@treturn integer nid of asn1_object ++*/ + static int openssl_asn1object_nid(lua_State* L) + { + ASN1_OBJECT* o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object"); +- lua_pushinteger(L, o->nid); ++ lua_pushinteger(L, OBJ_obj2nid(o)); + return 1; + } + ++/*** ++get name of asn1_object. ++ ++@function name ++@treturn string short name and followed by long name of asn1_object ++*/ + static int openssl_asn1object_name(lua_State* L) + { + ASN1_OBJECT* o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object"); +- lua_pushstring(L, o->sn); +- lua_pushstring(L, o->ln); ++ int nid = OBJ_obj2nid(o); ++ lua_pushstring(L, OBJ_nid2sn(nid)); ++ lua_pushstring(L, OBJ_nid2ln(nid)); + return 2; + } + ++/*** ++get long name of asn1_object. ++ ++@function ln ++@treturn string long name of asn1_object ++*/ + static int openssl_asn1object_ln(lua_State* L) + { + ASN1_OBJECT* o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object"); +@@ -348,6 +792,11 @@ static int openssl_asn1object_ln(lua_Sta + return 1; + } + ++/*** ++get short name of asn1_object. ++@function sn ++@treturn string short name of asn1_object ++*/ + static int openssl_asn1object_sn(lua_State* L) + { + ASN1_OBJECT* o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object"); +@@ -359,6 +808,13 @@ static int openssl_asn1object_sn(lua_Sta + return 1; + } + ++/*** ++get text of asn1_object. ++ ++@function txt ++@tparam[opt] boolean no_name true for only oid or name, default with false ++@treturn string long or short name, even oid of asn1_object ++*/ + static int openssl_asn1object_txt(lua_State* L) + { + ASN1_OBJECT* o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object"); +@@ -372,6 +828,13 @@ static int openssl_asn1object_txt(lua_St + return 1; + } + ++/*** ++compare two asn1_objects, if equals return true ++ ++@function equals ++@tparam asn1_object another to compre ++@treturn boolean true if equals ++*/ + static int openssl_asn1object_equals(lua_State* L) + { + ASN1_OBJECT* o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object"); +@@ -381,6 +844,12 @@ static int openssl_asn1object_equals(lua + return 1; + } + ++/*** ++get data of asn1_object ++ ++@function data ++@treturn string asn1_object data ++*/ + static int openssl_asn1object_data(lua_State* L) + { + ASN1_OBJECT* s = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object"); +@@ -401,6 +870,12 @@ static int openssl_asn1object_free(lua_S + return 0; + } + ++/*** ++make a clone of asn1_object ++ ++@function dup ++@treturn asn1_object clone for self ++*/ + static int openssl_asn1object_dup(lua_State* L) + { + ASN1_OBJECT* o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object"); +@@ -419,6 +894,7 @@ static luaL_Reg asn1obj_funcs[] = + {"txt", openssl_asn1object_txt}, + {"dup", openssl_asn1object_dup}, + {"data", openssl_asn1object_data}, ++ {"equals", openssl_asn1object_equals}, + + {"__eq", openssl_asn1object_equals}, + {"__gc", openssl_asn1object_free}, +@@ -427,123 +903,10 @@ static luaL_Reg asn1obj_funcs[] = + {NULL, NULL} + }; + +- +-static int openssl_asn1object_new(lua_State* L) +-{ +- if (lua_type(L, 1) == LUA_TNUMBER) +- { +- int nid = luaL_checkint(L, 1); +- ASN1_OBJECT* obj = OBJ_nid2obj(nid); +- if (obj) +- PUSH_OBJECT(obj, "openssl.asn1_object"); +- else +- lua_pushnil(L); +- } +- else if (lua_isstring(L, 1)) +- { +- const char* txt = luaL_checkstring(L, 1); +- int no_name = lua_isnone(L, 2) ? 0 : lua_toboolean(L, 2); +- +- ASN1_OBJECT* obj = OBJ_txt2obj(txt, no_name); +- if (obj) +- PUSH_OBJECT(obj, "openssl.asn1_object"); +- else +- lua_pushnil(L); +- } +- else if (lua_istable(L, 1)) +- { +- const char *oid, *sn, *ln; +- ASN1_OBJECT* obj; +- int nid; +- +- lua_getfield(L, 1, "oid"); +- luaL_argcheck(L, lua_isstring(L, -1), 1, "not have oid field or is not string"); +- oid = luaL_checkstring(L, -1); +- lua_pop(L, 1); +- +- lua_getfield(L, 1, "sn"); +- luaL_argcheck(L, lua_isstring(L, -1), 1, "not have sn field or is not string"); +- sn = luaL_checkstring(L, -1); +- lua_pop(L, 1); +- +- lua_getfield(L, 1, "ln"); +- luaL_argcheck(L, lua_isstring(L, -1), 1, "not have ln field or is not string"); +- ln = luaL_checkstring(L, -1); +- lua_pop(L, 1); +- +- if (OBJ_txt2nid(oid) != NID_undef) +- { +- luaL_argerror(L, 1, "oid already exist"); +- } +- +- if (OBJ_sn2nid(sn) != NID_undef) +- { +- luaL_argerror(L, 1, "sn already exist"); +- } +- +- if (OBJ_ln2nid(ln) != NID_undef) +- { +- luaL_argerror(L, 1, "ln already exist"); +- } +- +- nid = OBJ_create(oid, sn, ln); +- if (nid != NID_undef) +- { +- obj = OBJ_nid2obj(nid); +- PUSH_OBJECT(obj, "openssl.asn1_object"); +- } +- else +- luaL_argerror(L, 1, "create object fail"); +- } +- else +- luaL_argerror(L, 1, "need accept paramater"); +- +- return 1; +-} +- +-static int openssl_txt2nid(lua_State*L) +-{ +- const char* txt = luaL_checkstring(L, 1); +- int nid = OBJ_txt2nid(txt); +- if (nid != NID_undef) +- { +- lua_pushinteger(L, nid); +- } +- else +- lua_pushnil(L); +- +- return 1; +-} +- +-static int openssl_asn1string_new(lua_State* L) +-{ +- size_t size = 0; +- const char* data = luaL_checklstring(L, 1, &size); +- int type = luaL_checkint(L, 2); +- ASN1_STRING *s = ASN1_STRING_type_new(type); +- ASN1_STRING_set(s, data, size); +- PUSH_OBJECT(s, "openssl.asn1_string"); +- return 1; +-} +- +-static int openssl_asn1int_new(lua_State* L) +-{ +- ASN1_INTEGER *ai = ASN1_INTEGER_new(); +- if (lua_isinteger(L, 1)) +- { +- long v = luaL_checklong(L, 1); +- ASN1_INTEGER_set(ai, v); +- } +- else if (!lua_isnone(L, 1)) +- { +- BIGNUM *bn = BN_get(L, 1); +- ai = BN_to_ASN1_INTEGER(bn, ai); +- BN_free(bn); +- } +- PUSH_OBJECT(ai, "openssl.asn1_integer"); +- return 1; +-} +- ++/*** ++openssl.asn1_integer object ++@type asn1_integer ++*/ + static int openssl_asn1int_bn(lua_State *L) + { + ASN1_INTEGER *ai = CHECK_OBJECT(1, ASN1_INTEGER, "openssl.asn1_integer"); +@@ -562,6 +925,14 @@ static int openssl_asn1int_bn(lua_State + } + } + ++/*** ++openssl.asn1_string object ++@type asn1_string ++*/ ++ ++/*** ++@function set ++*/ + static int openssl_asn1group_set(lua_State *L) + { + ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -637,6 +1008,9 @@ static time_t ASN1_TIME_get(ASN1_TIME* t + return mktime(&t) + off; + } + ++/*** ++@function get ++*/ + static int openssl_asn1group_get(lua_State *L) + { + ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -664,6 +1038,9 @@ static int openssl_asn1group_get(lua_Sta + return 0; + } + ++/*** ++@function i2d ++*/ + static int openssl_asn1group_i2d(lua_State *L) + { + ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -716,6 +1093,9 @@ static int openssl_asn1group_i2d(lua_Sta + return 0; + } + ++/*** ++@function d2i ++*/ + static int openssl_asn1group_d2i(lua_State *L) + { + ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -732,7 +1112,6 @@ static int openssl_asn1group_d2i(lua_Sta + else + lua_pushvalue(L, 1); + return 1; +- break; + } + case V_ASN1_UTCTIME: + { +@@ -763,6 +1142,13 @@ static int openssl_asn1group_d2i(lua_Sta + return 0; + } + ++/*** ++get type of asn1_string ++ ++@function type ++@treturn string type of asn1_string ++@see new_string ++*/ + static int openssl_asn1group_type(lua_State* L) + { + ASN1_STRING* s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -780,6 +1166,17 @@ static int openssl_asn1group_type(lua_St + return 1; + } + ++/*** ++get length two asn1_string ++ ++@function length ++@treturn integer length of asn1_string ++@usage ++ local astr = asn1.new_string('ABCD') ++ print('length:',#astr) ++ print('length:',astr:length()) ++ assert(#astr==astr:length,"must equals") ++*/ + static int openssl_asn1group_length(lua_State* L) + { + ASN1_STRING* s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -787,6 +1184,21 @@ static int openssl_asn1group_length(lua_ + return 1; + } + ++/*** ++get data of asn1_string ++ ++@function data ++@treturn string raw data of asn1_string ++*/ ++ ++/*** ++set data of asn1_string ++ ++@function data ++@tparam string data set to asn1_string ++@treturn boolean success if value set true, or follow by errmsg ++@treturn string fail error message ++*/ + static int openssl_asn1group_data(lua_State* L) + { + ASN1_STRING* s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -802,6 +1214,16 @@ static int openssl_asn1group_data(lua_St + return 1; + } + ++/*** ++compare two asn1_string, if equals return true ++ ++@function equals ++@tparam asn1_string another to compre ++@treturn boolean true if equals ++@usage ++ local obj = astr:dup() ++ assert(obj==astr, "must equals") ++*/ + static int openssl_asn1group_eq(lua_State* L) + { + ASN1_STRING* s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -835,6 +1257,12 @@ static int openssl_asn1group_free(lua_St + return 0; + } + ++/*** ++convert asn1_string to lua string ++ ++@function __tostring ++@treturn string result format match with type:data ++*/ + static int openssl_asn1group_tostring(lua_State* L) + { + ASN1_STRING* s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -862,6 +1290,12 @@ static int openssl_asn1group_tostring(lu + return 0; + } + ++/*** ++get data as printable encode string ++ ++@function toprint ++@treturn string printable encoded string ++*/ + static int openssl_asn1group_toprint(lua_State* L) + { + ASN1_STRING* s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -893,6 +1327,12 @@ static int openssl_asn1group_toprint(lua + return 1; + } + ++/*** ++get data as utf8 encode string ++ ++@function toutf8 ++@treturn string utf8 encoded string ++*/ + static int openssl_asn1group_toutf8(lua_State* L) + { + ASN1_STRING* s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -906,6 +1346,12 @@ static int openssl_asn1group_toutf8(lua_ + return 1; + } + ++/*** ++duplicate a new asn1_string ++ ++@function dup ++@treturn asn1_string clone for self ++*/ + static int openssl_asn1group_dup(lua_State* L) + { + ASN1_STRING* s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group"); +@@ -913,53 +1359,6 @@ static int openssl_asn1group_dup(lua_Sta + return 1; + } + +-static int openssl_asn1generalizedtime_new(lua_State* L) +-{ +- ASN1_GENERALIZEDTIME* a = NULL; +- int ret = 1; +- luaL_argcheck(L, +- 1, +- lua_isnone(L, 1) || lua_isnumber(L, 1) || lua_isstring(L, 1), +- "must be number, string or none" +- ); +- a = ASN1_GENERALIZEDTIME_new(); +- if (lua_isnumber(L, 1)) +- ASN1_GENERALIZEDTIME_set(a, luaL_checkinteger(L, 1)); +- else if (lua_isstring(L, 1)) +- ret = ASN1_GENERALIZEDTIME_set_string(a, lua_tostring(L, 1)); +- +- if (ret == 1) +- PUSH_OBJECT(a, "openssl.asn1_time"); +- else +- return openssl_pushresult(L, ret); +- return 1; +-} +- +-static int openssl_asn1utctime_new(lua_State* L) +-{ +- ASN1_UTCTIME* a = NULL; +- int ret = 1; +- luaL_argcheck(L, +- 1, +- lua_isnone(L, 1) || lua_isnumber(L, 1) || lua_isstring(L, 1), +- "must be number, string or none" +- ); +- a = ASN1_UTCTIME_new(); +- if (lua_isnumber(L, 1)) +- { +- time_t t = luaL_checkinteger(L, 1); +- ASN1_TIME_set(a, t); +- } +- else if (lua_isstring(L, 1)) +- ret = ASN1_TIME_set_string(a, lua_tostring(L, 1)); +- +- if (ret == 1) +- PUSH_OBJECT(a, "openssl.asn1_time"); +- else +- return openssl_pushresult(L, ret); +- return 1; +-} +- + static int openssl_asn1time_check(lua_State* L) + { + ASN1_TIME *a = CHECK_OBJECT(1, ASN1_TIME, "openssl.asn1_time"); +@@ -992,7 +1391,7 @@ static luaL_Reg asn1str_funcs[] = + {"tostring", openssl_asn1group_tostring}, + + {"__len", openssl_asn1group_length}, +- {"__tostring", auxiliar_tostring}, ++ {"__tostring",auxiliar_tostring}, + + {"__eq", openssl_asn1group_eq}, + {"__gc", openssl_asn1group_free}, +@@ -1012,157 +1411,8 @@ static luaL_Reg asn1str_funcs[] = + {NULL, NULL} + }; + +-static int openssl_get_object(lua_State*L) +-{ +- size_t l = 0; +- const char* asn1s = luaL_checklstring(L, 1, &l); +- size_t off = posrelat(luaL_optinteger(L, 2, 1), l); +- size_t length = posrelat(luaL_optinteger(L, 3, l), l); +- +- const unsigned char *p = (const unsigned char *)asn1s + off - 1; +- long len = 0; +- int tag = 0; +- int class = 0; +- int ret; +- +- p = (const unsigned char *)asn1s + off - 1; +- ret = ASN1_get_object(&p, &len, &tag, &class, length - off + 1); +- if (ret & 0x80) +- { +- lua_pushnil(L); +- lua_pushstring(L, "arg 1 with error encoding"); +- lua_pushinteger(L, ret); +- return 3; +- } +- lua_pushinteger(L, tag); +- lua_pushinteger(L, class); +- lua_pushinteger(L, p - (const unsigned char *)asn1s + 1); +- lua_pushinteger(L, p + len - (const unsigned char *)asn1s); +- +- lua_pushboolean(L, ret & V_ASN1_CONSTRUCTED); +- return 5; +-} +- +-static int openssl_put_object(lua_State*L) +-{ +- int tag = luaL_checkint(L, 1); +- int cls = luaL_checkint(L, 2); +- int length = 0; +- int constructed; +- unsigned char *p1, *p2; +- const char* dat = NULL; +- luaL_Buffer B; +- +- luaL_argcheck(L, +- lua_isnoneornil(L, 3) || lua_type(L, 3) == LUA_TNUMBER || lua_isstring(L, 3), 3, +- "if exist only accept string or number"); +- luaL_argcheck(L, lua_isnoneornil(L, 4) || lua_isboolean(L, 4), 4, +- "if exist must be boolean type"); +- +- if (lua_isnoneornil(L, 3)) +- { +- /* constructed == 2 for indefinite length constructed */ +- constructed = 2; +- length = 0; +- } +- else +- { +- if (lua_type(L, 3) == LUA_TNUMBER) +- { +- length = lua_tointeger(L, 3); +- } +- else if (lua_isstring(L, 3)) +- { +- size_t l; +- dat = lua_tolstring(L, 3, &l); +- length = (int)l; +- } +- +- constructed = lua_isnoneornil(L, 4) ? 0 : lua_toboolean(L, 4); +- } +- luaL_buffinit(L, &B); +- p1 = (unsigned char *)luaL_prepbuffer(&B); +- p2 = p1; +- +- ASN1_put_object(&p2, constructed, length, tag, cls); +- luaL_addsize(&B, p2 - p1); +- if (dat) +- { +- luaL_addlstring(&B, dat, length); +- } +- luaL_pushresult(&B); +- return 1; +-}; +- +-static int openssl_asn1_tostring(lua_State*L) +-{ +- int val = luaL_checkint(L, 1); +- const char* range = luaL_optstring(L, 2, NULL); +- int i; +- +- if (range == NULL) +- { +- for (i = 0; i < sizeof(asn1_const) / sizeof(LuaL_Enum) - 1; i++) +- { +- if (asn1_const[i].val == val) +- { +- lua_pushstring(L, asn1_const[i + CLS_IDX_OFFSET].name); +- return 1; +- } +- } +- } +- else if (strcmp("tag", range) == 0) +- { +- for (i = 0; i < TAG_IDX_LENGTH; i++) +- { +- if (asn1_const[i + TAG_IDX_OFFSET].val == val) +- { +- lua_pushstring(L, asn1_const[i + TAG_IDX_OFFSET].name); +- return 1; +- } +- } +- } +- else if (strcmp("class", range) == 0) +- { +- for (i = 0; i < CLS_IDX_LENGTH; i++) +- { +- if (asn1_const[i + CLS_IDX_OFFSET].val == val) +- { +- lua_pushstring(L, asn1_const[i + CLS_IDX_OFFSET].name); +- return 1; +- } +- } +- } +- +- return 0; +-} +- +-static luaL_Reg R[] = +-{ +- {"new_object", openssl_asn1object_new}, +- +- {"new_integer", openssl_asn1int_new}, +- {"new_string", openssl_asn1string_new}, +- {"new_utctime", openssl_asn1utctime_new}, +- {"new_generalizedtime", openssl_asn1generalizedtime_new}, +- +- {"new_type", openssl_asn1type_new}, +- {"d2i_asn1type", openssl_asn1type_d2i}, +- +- {"get_object", openssl_get_object}, +- {"put_object", openssl_put_object}, +- +- {"tostring", openssl_asn1_tostring}, +- +- {"txt2nid", openssl_txt2nid}, +- +- +- {NULL, NULL} +-}; +- + int luaopen_asn1(lua_State *L) + { +- int i; + tzset(); + auxiliar_newclass(L, "openssl.asn1_object", asn1obj_funcs); + auxiliar_newclass(L, "openssl.asn1_type", asn1type_funcs); +@@ -1182,12 +1432,7 @@ int luaopen_asn1(lua_State *L) + lua_pushliteral(L, MYVERSION); + lua_settable(L, -3); + +- for (i = 0; i < sizeof(asn1_const) / sizeof(LuaL_Enum) - 1; i++) +- { +- LuaL_Enum e = asn1_const[i]; +- lua_pushinteger(L, e.val); +- lua_setfield(L, -2, e.name); +- } ++ auxiliar_enumerate(L, -1, asn1_const); + + return 1; + } +@@ -1212,7 +1457,7 @@ int openssl_get_nid(lua_State*L, int idx + else if (lua_isuserdata(L, idx)) + { + ASN1_OBJECT* obj = CHECK_OBJECT(idx, ASN1_OBJECT, "openssl.asn1_object"); +- return obj->nid; ++ return OBJ_obj2nid(obj); + } + else + { +@@ -1229,9 +1474,18 @@ int openssl_push_asn1object(lua_State* L + return 1; + } + +-int openssl_push_asn1(lua_State* L, ASN1_STRING* string, int type) ++int openssl_push_asn1(lua_State* L, const ASN1_STRING* string, int type) + { +- if (type == V_ASN1_UNDEF) ++ if (string == NULL) ++ { ++ lua_pushnil(L); ++ return 1; ++ } ++ if ((string->type & V_ASN1_GENERALIZEDTIME) == V_ASN1_GENERALIZEDTIME && type == V_ASN1_UTCTIME) ++ type = V_ASN1_GENERALIZEDTIME; ++ else if ((string->type & V_ASN1_UTCTIME) == V_ASN1_UTCTIME && type == V_ASN1_GENERALIZEDTIME) ++ type = V_ASN1_UTCTIME; ++ else if (type == V_ASN1_UNDEF) + type = string->type; + if ((string->type & type) != type) + { +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/auxiliar.c luvi-src-v2.7.6/deps/lua-openssl/src/auxiliar.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/auxiliar.c 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/auxiliar.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,41 +0,0 @@ +-#include "../deps/auxiliar/auxiliar.c" +- +-#if LUA_VERSION_NUM==501 +-#define lua_rawlen lua_strlen +-#define luaL_typeerror luaL_typerror +-#endif +-/*=========================================================================*\ +-* Exported functions +-\*=========================================================================*/ +- +-int auxiliar_isclass(lua_State *L, const char *classname, int objidx) +-{ +- void *p = lua_touserdata(L, objidx); +- if (p != NULL) /* value is a userdata? */ +- { +- if (lua_getmetatable(L, objidx)) /* does it have a metatable? */ +- { +- lua_getfield(L, LUA_REGISTRYINDEX, classname); /* get correct metatable */ +- if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */ +- { +- lua_pop(L, 2); /* remove both metatables */ +- return 1; +- } +- else +- lua_pop(L, 2); +- } +- } +- return 0; +-} +- +-int auxiliar_isgroup(lua_State *L, const char *groupname, int objidx) +-{ +- void *data = auxiliar_getgroupudata(L, groupname, objidx); +- return data != NULL; +-} +- +-int auxiliar_checkoption(lua_State*L, int objidx, const char* def, const char* const slist[], const int ival[]) +-{ +- int at = luaL_checkoption(L, objidx, def, slist); +- return ival[at]; +-} +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/auxiliar.h luvi-src-v2.7.6/deps/lua-openssl/src/auxiliar.h +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/auxiliar.h 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/auxiliar.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,37 +0,0 @@ +-#ifndef AUXILIAR_H_EXT +-#define AUXILIAR_H_EXT +-#include "../deps/auxiliar/auxiliar.h" +- +-#define AUXILIAR_SET(L,tidx, lvar, cval, ltype) \ +- do { \ +- int n = tidx < 0 ? tidx-1 : tidx; \ +- lua_push##ltype(L, (cval)); \ +- lua_setfield(L, n, lvar); \ +- } while(0) +- +-#define AUXILIAR_SETLSTR(L,tidx, lvar, cval,len) \ +- do { \ +- int n = tidx < 0 ? tidx-1 : tidx; \ +- lua_pushlstring(L, (const char*)(cval),len); \ +- lua_setfield(L, n, lvar); \ +- } while(0) +- +-#define AUXLIAR_GET(L,tidx, lvar, cvar, ltype) \ +- do { \ +- lua_getfield(L, tidx, lvar); \ +- cvar = lua_to##ltype(L, -1); \ +- lua_pop(L, 1); \ +- } while(0) +- +-typedef struct +-{ +- const char* name; +- int val; +-} LuaL_Enum; +- +-int auxiliar_isclass(lua_State *L, const char *classname, int objidx); +-int auxiliar_isgroup(lua_State *L, const char *groupname, int objidx); +- +-int auxiliar_checkoption(lua_State*L, int objidx, const char* def, const char* const slist[], const int ival[]); +- +-#endif /* AUXILIAR_H_EXT */ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/bio.c luvi-src-v2.7.6/deps/lua-openssl/src/bio.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/bio.c 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/bio.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,10 +1,11 @@ +-/*=========================================================================*\ +-* bio.c +-* bio object for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ +- ++/*** ++bio object for lua-openssl binding, mapping to BIO in openssl ++openssl.bio is a help object, it is useful, but rarely use. ++ ++@module bio ++@usage ++ bio = require'openssl'.bio ++*/ + #include "openssl.h" + #include "private.h" + #include +@@ -53,7 +54,6 @@ luaL_error(L, "error opening the file(%s + PUSH_OBJECT(bio,"openssl.bio"); + return 1; + } +- + */ + + static const char* close_flags[] = +@@ -63,6 +63,13 @@ static const char* close_flags[] = + NULL + }; + ++/*** ++make string as bio object ++ ++@function mem ++@tparam[opt=nil] string data, it will be memory buffer data ++@treturn bio it can be input or output object ++*/ + static LUA_FUNCTION(openssl_bio_new_mem) + { + size_t l = 0; +@@ -78,11 +85,19 @@ static LUA_FUNCTION(openssl_bio_new_mem) + BIO_write(bio, d, l); + } + +- BIO_set_close(bio, BIO_CLOSE); ++ (void)BIO_set_close(bio, BIO_CLOSE); + PUSH_OBJECT(bio, "openssl.bio"); + return 1; + } + ++/*** ++make tcp bio from socket fd ++ ++@function socket ++@tparam number fd ++@tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc ++@treturn bio ++*/ + static LUA_FUNCTION(openssl_bio_new_socket) + { + int s = luaL_checkint(L, 1); +@@ -93,6 +108,14 @@ static LUA_FUNCTION(openssl_bio_new_sock + return 1; + } + ++/*** ++make dgram bio from socket fd ++ ++@function dgram ++@tparam number fd ++@tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc ++@treturn bio ++*/ + static LUA_FUNCTION(openssl_bio_new_dgram) + { + int s = luaL_checkint(L, 1); +@@ -102,6 +125,13 @@ static LUA_FUNCTION(openssl_bio_new_dgra + return 1; + } + ++/*** ++make socket or file bio with fd ++@function fd ++@tparam number fd ++@tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc ++@treturn bio ++*/ + static LUA_FUNCTION(openssl_bio_new_fd) + { + int fd = luaL_checkint(L, 1); +@@ -112,6 +142,13 @@ static LUA_FUNCTION(openssl_bio_new_fd) + return 1; + } + ++/*** ++make file object with file name or path ++@function file ++@tparam string file ++@tparam[opt='r'] string mode ++@treturn bio ++*/ + static LUA_FUNCTION(openssl_bio_new_file) + { + const char* f = luaL_checkstring(L, 1); +@@ -123,6 +160,12 @@ static LUA_FUNCTION(openssl_bio_new_file + return 1; + } + ++/*** ++make tcp listen socket ++@function accept ++@tparam string host_port address like 'host:port' ++@treturn bio ++*/ + static LUA_FUNCTION(openssl_bio_new_accept) + { + const char* port = lua_tostring(L, 1); +@@ -132,6 +175,13 @@ static LUA_FUNCTION(openssl_bio_new_acce + return 1; + } + ++/*** ++make tcp client socket ++@function connect ++@tparam string host_addr addrees like 'host:port' ++@tparam[opt=true] boolean connect default connect immediately ++@treturn bio ++*/ + static int openssl_bio_new_connect(lua_State *L) + { + const char *host = luaL_checkstring(L, 1); +@@ -167,7 +217,7 @@ static int openssl_bio_new_connect(lua_S + openssl_newvalue(L, bio); + + lua_pushboolean(L, 1); +- openssl_setvalue(L, bio, "free_all"); ++ openssl_valueset(L, bio, "free_all"); + return 1; + } + else +@@ -183,6 +233,36 @@ static int openssl_bio_new_connect(lua_S + return 0; + } + ++/*** ++Create base64 or buffer bio, which can append to an io BIO object ++@function filter ++@tparam string mode support 'base64' or 'buffer' ++@treturn bio ++*/ ++/*** ++Create digest bio, which can append to an io BIO object ++@function filter ++@tparam string mode must be 'digest' ++@tparam evp_md|string md_alg ++@treturn bio ++*/ ++/*** ++Create ssl bio ++@function filter ++@tparam string mode must be 'ssl' ++@tparam ssl s ++@tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc ++@treturn bio ++*/ ++/*** ++create cipher filter bio object ++@function filter ++@tparam string mode must be 'cipher' ++@tparam string key ++@tparam string iv ++@tparam[opt=true] boolean encrypt ++@treturn bio ++*/ + static LUA_FUNCTION(openssl_bio_new_filter) + { + /* 0 1 2 3 4 5 */ +@@ -213,7 +293,7 @@ static LUA_FUNCTION(openssl_bio_new_filt + break; + case 3: + { +- const EVP_MD* md = get_digest(L, 2); ++ const EVP_MD* md = get_digest(L, 2, NULL); + bio = BIO_new(BIO_f_md()); + ret = BIO_set_md(bio, md); + } +@@ -236,7 +316,7 @@ static LUA_FUNCTION(openssl_bio_new_filt + openssl_newvalue(L, bio); + + lua_pushboolean(L, 1); +- openssl_setvalue(L, bio, "free_all"); ++ openssl_valueset(L, bio, "free_all"); + } + return 1; + } +@@ -249,6 +329,17 @@ static LUA_FUNCTION(openssl_bio_new_filt + } + + /* bio object method */ ++/*** ++openssl.bio object ++@type bio ++*/ ++ ++/*** ++read data from bio object ++@function read ++@tparam number len ++@treturn string string length may be less than param len ++*/ + static LUA_FUNCTION(openssl_bio_read) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -280,6 +371,12 @@ static LUA_FUNCTION(openssl_bio_read) + return ret; + } + ++/*** ++get line from bio object ++@function gets ++@tparam[opt=256] number max line len ++@treturn string string length may be less than param len ++*/ + static LUA_FUNCTION(openssl_bio_gets) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -310,7 +407,12 @@ static LUA_FUNCTION(openssl_bio_gets) + return ret; + } + +- ++/*** ++write data to bio object ++@function write ++@tparam string data ++@treturn number length success write ++*/ + static LUA_FUNCTION(openssl_bio_write) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -339,6 +441,12 @@ static LUA_FUNCTION(openssl_bio_write) + return ret; + } + ++/*** ++put line to bio object ++@function puts ++@tparam string data ++@treturn number length success write ++*/ + static LUA_FUNCTION(openssl_bio_puts) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -365,6 +473,11 @@ static LUA_FUNCTION(openssl_bio_puts) + return ret; + } + ++/*** ++flush buffer of bio object ++@function flush ++@treturn boolean true for success, others for fail ++*/ + static LUA_FUNCTION(openssl_bio_flush) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -382,7 +495,7 @@ static LUA_FUNCTION(openssl_bio_free) + all = lua_toboolean(L, 2); + else + { +- openssl_getvalue(L, bio, "free_all"); ++ openssl_valueget(L, bio, "free_all"); + all = lua_toboolean(L, -1); + lua_pop(L, 1); + } +@@ -396,6 +509,11 @@ static LUA_FUNCTION(openssl_bio_free) + return 0; + } + ++/*** ++get type of bio ++@function type ++@treturn string ++*/ + static LUA_FUNCTION(openssl_bio_type) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -403,6 +521,12 @@ static LUA_FUNCTION(openssl_bio_type) + return 1; + } + ++/*** ++set nonblock for bio object ++@function nbio ++@tparam boolean nonblock ++@treturn boolean result, true for success, others for fail ++*/ + static LUA_FUNCTION(openssl_bio_nbio) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -428,16 +552,24 @@ static LUA_FUNCTION(openssl_bio_retry) + return 1; + } + +- +- ++/*** ++reset bio ++@function reset ++*/ + static LUA_FUNCTION(openssl_bio_reset) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +- BIO_reset(bio); ++ (void)BIO_reset(bio); + return 0; + } + + /* filter bio object */ ++/*** ++push bio append to chain of bio, if want to free a chain use free_all() ++@function push ++@tparam bio append ++@treturn bio ++*/ + static LUA_FUNCTION(openssl_bio_push) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -450,23 +582,33 @@ static LUA_FUNCTION(openssl_bio_push) + return 1; + } + ++/*** ++remove bio from chain ++@function pop ++@tparam bio toremove ++*/ + static LUA_FUNCTION(openssl_bio_pop) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); + BIO* end = BIO_pop(bio); +- if (end) ++ if (end == NULL) + { + lua_pushnil(L); + } + else + { +- CRYPTO_add(&end->references, 1, CRYPTO_LOCK_BIO); ++ BIO_up_ref(end); + PUSH_OBJECT(end, "openssl.bio"); + } + return 1; + } + + /* mem */ ++/*** ++get mem data, only support mem bio object ++@function get_mem ++@treturn string ++*/ + static LUA_FUNCTION(openssl_bio_get_mem) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -482,7 +624,13 @@ static LUA_FUNCTION(openssl_bio_get_mem) + } + + /* network socket */ +- ++/*** ++setup ready and accept client connect ++@function accept ++@tparam[opt=false] boolean setup true for setup accept bio, false or none will accept client connect ++@treturn[1] boolean result only when setup is true ++@treturn[2] bio accpeted bio object ++*/ + static LUA_FUNCTION(openssl_bio_accept) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -498,7 +646,7 @@ static LUA_FUNCTION(openssl_bio_accept) + openssl_newvalue(L, nb); + + lua_pushboolean(L, 1); +- openssl_setvalue(L, nb, "free_all"); ++ openssl_valueset(L, nb, "free_all"); + return 1; + } + else +@@ -510,6 +658,10 @@ static LUA_FUNCTION(openssl_bio_accept) + return 0; + } + ++/*** ++shutdown SSL or TCP connection ++@function shutdown ++*/ + static LUA_FUNCTION(openssl_bio_shutdown) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -520,14 +672,18 @@ static LUA_FUNCTION(openssl_bio_shutdown + } + else if (BIO_method_type(bio) & (BIO_TYPE_SOCKET | BIO_TYPE_FD)) + { +- BIO_shutdown_wr(bio);; ++ (void)BIO_shutdown_wr(bio);; + } + else + luaL_error(L, "don't know how to shutdown"); + return 0; + } + +- ++/*** ++get ssl object assosited with bio object ++@function get_ssl ++@treturn ssl ++*/ + static LUA_FUNCTION(openssl_bio_get_ssl) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -543,6 +699,11 @@ static LUA_FUNCTION(openssl_bio_get_ssl) + return 0; + } + ++/*** ++do TCP or SSL connect ++@function connect ++@treturn booolean result true for success and others for fail ++*/ + static LUA_FUNCTION(openssl_bio_connect) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -550,6 +711,11 @@ static LUA_FUNCTION(openssl_bio_connect) + return openssl_pushresult(L, ret); + } + ++/*** ++do handshake of TCP or SSL connection ++@function handshake ++@treturn boolean result true for success, and others for fail ++*/ + static LUA_FUNCTION(openssl_bio_handshake) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -557,6 +723,17 @@ static LUA_FUNCTION(openssl_bio_handshak + return openssl_pushresult(L, ret); + } + ++/*** ++get fd of bio object ++@function fd ++@treturn number ++*/ ++/*** ++set fd of bio object ++@function fd ++@tparam number fd ++@treturn number fd ++*/ + static LUA_FUNCTION(openssl_bio_fd) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -584,71 +761,68 @@ void BIO_info_callback(BIO *bio, int cmd + BIO *b; + char buf[256]; + char *p; +- long r = 1; + size_t p_maxlen; + (void) argl; + (void) argp; +- if (BIO_CB_RETURN & cmd) +- r = ret; + +- BIO_snprintf(buf, sizeof buf, "BIO[%08lX]:", (unsigned long)bio); ++ snprintf(buf, sizeof buf, "BIO[%p]:", bio); + p = &(buf[14]); + p_maxlen = sizeof buf - 14; + switch (cmd) + { + case BIO_CB_FREE: +- BIO_snprintf(p, p_maxlen, "Free - %s\n", bio->method->name); ++ snprintf(p, p_maxlen, "Free - %s\n", BIO_method_name(bio)); + break; + case BIO_CB_READ: +- if (bio->method->type & BIO_TYPE_DESCRIPTOR) +- BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s fd=%d\n", +- bio->num, (unsigned long)argi, +- bio->method->name, bio->num); ++ if (BIO_method_type(bio) & BIO_TYPE_DESCRIPTOR) ++ snprintf(p, p_maxlen, "read(%lu,%lu) - %s fd=%lu\n", ++ BIO_number_read(bio), (unsigned long)argi, ++ BIO_method_name(bio), BIO_number_read(bio)); + else +- BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s\n", +- bio->num, (unsigned long)argi, +- bio->method->name); ++ snprintf(p, p_maxlen, "read(%lu,%lu) - %s\n", ++ BIO_number_read(bio), (unsigned long)argi, ++ BIO_method_name(bio)); + break; + case BIO_CB_WRITE: +- if (bio->method->type & BIO_TYPE_DESCRIPTOR) +- BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s fd=%d\n", +- bio->num, (unsigned long)argi, +- bio->method->name, bio->num); ++ if (BIO_method_type(bio) & BIO_TYPE_DESCRIPTOR) ++ snprintf(p, p_maxlen, "write(%lu,%lu) - %s fd=%lu\n", ++ BIO_number_written(bio), (unsigned long)argi, ++ BIO_method_name(bio), BIO_number_written(bio)); + else +- BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s\n", +- bio->num, (unsigned long)argi, +- bio->method->name); ++ snprintf(p, p_maxlen, "write(%lu,%lu) - %s\n", ++ BIO_number_written(bio), (unsigned long)argi, ++ BIO_method_name(bio)); + break; + case BIO_CB_PUTS: +- BIO_snprintf(p, p_maxlen, "puts() - %s\n", bio->method->name); ++ snprintf(p, p_maxlen, "puts() - %s\n", BIO_method_name(bio)); + break; + case BIO_CB_GETS: +- BIO_snprintf(p, p_maxlen, "gets(%lu) - %s\n", (unsigned long)argi, bio->method->name); ++ snprintf(p, p_maxlen, "gets(%lu) - %s\n", (unsigned long)argi, BIO_method_name(bio)); + break; + case BIO_CB_CTRL: +- BIO_snprintf(p, p_maxlen, "ctrl(%lu) - %s\n", (unsigned long)argi, bio->method->name); ++ snprintf(p, p_maxlen, "ctrl(%lu) - %s\n", (unsigned long)argi, BIO_method_name(bio)); + break; + case BIO_CB_RETURN|BIO_CB_READ: +- BIO_snprintf(p, p_maxlen, "read return %ld\n", ret); ++ snprintf(p, p_maxlen, "read return %ld\n", ret); + break; + case BIO_CB_RETURN|BIO_CB_WRITE: +- BIO_snprintf(p, p_maxlen, "write return %ld\n", ret); ++ snprintf(p, p_maxlen, "write return %ld\n", ret); + break; + case BIO_CB_RETURN|BIO_CB_GETS: +- BIO_snprintf(p, p_maxlen, "gets return %ld\n", ret); ++ snprintf(p, p_maxlen, "gets return %ld\n", ret); + break; + case BIO_CB_RETURN|BIO_CB_PUTS: +- BIO_snprintf(p, p_maxlen, "puts return %ld\n", ret); ++ snprintf(p, p_maxlen, "puts return %ld\n", ret); + break; + case BIO_CB_RETURN|BIO_CB_CTRL: +- BIO_snprintf(p, p_maxlen, "ctrl return %ld\n", ret); ++ snprintf(p, p_maxlen, "ctrl return %ld\n", ret); + break; + default: +- BIO_snprintf(p, p_maxlen, "bio callback - unknown type (%d)\n", cmd); ++ snprintf(p, p_maxlen, "bio callback - unknown type (%d)\n", cmd); + break; + } + +- b = (BIO *)bio->cb_arg; ++ b = (BIO *)BIO_get_callback_arg(bio); + if (b != NULL) + BIO_write(b, buf, strlen(buf)); + #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) +@@ -657,6 +831,12 @@ void BIO_info_callback(BIO *bio, int cmd + #endif + } + ++/*** ++set callback function of bio information ++@function set_callback ++@tparam function callback ++@treturn boolean result true for success, and others for fail ++*/ + static LUA_FUNCTION(openssl_bio_set_callback) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -668,6 +848,11 @@ static LUA_FUNCTION(openssl_bio_set_call + return openssl_pushresult(L, ret); + } + ++/*** ++return pending length of bytes to read and write ++@function pending ++@treturn number pending of read, followed by pending of write ++*/ + static LUA_FUNCTION(openssl_bio_pending) + { + BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); +@@ -679,6 +864,16 @@ static LUA_FUNCTION(openssl_bio_pending) + return 2; + } + ++/*** ++free a chain ++@function free_all ++*/ ++ ++/*** ++close bio ++@function close ++*/ ++ + static luaL_Reg bio_funs[] = + { + /* generate operation */ +@@ -746,4 +941,3 @@ int luaopen_bio(lua_State *L) + + return 1; + } +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/callback.c luvi-src-v2.7.6/deps/lua-openssl/src/callback.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/callback.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/callback.c 2019-02-13 11:53:24.275126573 +0100 +@@ -13,17 +13,17 @@ static int verify_cb(int preverify_ok, X + { + int err = X509_STORE_CTX_get_error(xctx); + int depth = X509_STORE_CTX_get_error_depth(xctx); +- X509 *current = xctx->current_cert; ++ X509 *current = X509_STORE_CTX_get_current_cert(xctx); + + if (L) + { + /* get verify_cert state */ +- openssl_getvalue(L, ssl, "verify_cert"); ++ openssl_valueget(L, ssl, "verify_cert"); + if (lua_isnil(L, -1)) + { + lua_newtable(L); +- openssl_setvalue(L, ssl, "verify_cert"); +- openssl_getvalue(L, ssl, "verify_cert"); ++ openssl_valueset(L, ssl, "verify_cert"); ++ openssl_valueget(L, ssl, "verify_cert"); + } + + /* create current verify state table */ +@@ -42,11 +42,11 @@ static int verify_cb(int preverify_ok, X + if (current) + { + PUSH_OBJECT(current, "openssl.x509"); +- CRYPTO_add(¤t->references, 1, CRYPTO_LOCK_X509); ++ X509_up_ref(current); + lua_setfield(L, -2, "current_cert"); + } + +- openssl_getvalue(L, ctx, preverify_ok == -1 ? "cert_verify_cb" : "verify_cb"); ++ openssl_valueget(L, ctx, preverify_ok == -1 ? "cert_verify_cb" : "verify_cb"); + if (lua_isfunction(L, -1)) + { + /* this is set by SSL_CTX_set_verify */ +@@ -62,7 +62,7 @@ static int verify_cb(int preverify_ok, X + else + { + int always_continue, verify_depth; +- openssl_getvalue(L, ctx, "verify_cb_flags"); ++ openssl_valueget(L, ctx, "verify_cb_flags"); + /* + int verify_depth; + int always_continue; +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/cipher.c luvi-src-v2.7.6/deps/lua-openssl/src/cipher.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/cipher.c 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/cipher.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,10 +1,10 @@ +-/*=========================================================================*\ +-* cipher.c +-* cipher module for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++cipher module for lua-openssl binding + ++@module cipher ++@usage ++ cipher = require('openssl').cipher ++*/ + #include "openssl.h" + #include "private.h" + +@@ -12,6 +12,13 @@ + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + ++/*** ++list all support cipher algs ++ ++@function list ++@tparam[opt] boolean alias include alias names for cipher alg, default true ++@treturn[table] all cipher methods ++*/ + static LUA_FUNCTION(openssl_cipher_list) + { + int alias = lua_isnoneornil(L, 1) ? 1 : lua_toboolean(L, 1); +@@ -20,6 +27,15 @@ static LUA_FUNCTION(openssl_cipher_list) + return 1; + } + ++/*** ++get evp_cipher object ++ ++@function get ++@tparam string|integer|asn1_object alg name, nid or object identity ++@treturn evp_cipher cipher object mapping EVP_MD in openssl ++ ++@see evp_cipher ++*/ + static LUA_FUNCTION(openssl_cipher_get) + { + if (!lua_isuserdata(L, 1)) +@@ -33,12 +49,24 @@ static LUA_FUNCTION(openssl_cipher_get) + } + else + { +- luaL_argcheck(L, auxiliar_isclass(L, "openssl.evp_cipher", 1), 1, "only accept openssl.evp_cipher object"); ++ luaL_argcheck(L, auxiliar_getclassudata(L, "openssl.evp_cipher", 1), 1, "only accept openssl.evp_cipher object"); + lua_pushvalue(L, 1); + } + return 1; + } + ++/*** ++quick encrypt ++ ++@function encrypt ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam string input data to encrypt ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn string result encrypt data ++*/ + static LUA_FUNCTION(openssl_evp_encrypt) + { + const EVP_CIPHER* cipher = NULL; +@@ -116,6 +144,18 @@ static LUA_FUNCTION(openssl_evp_encrypt) + return 0; + } + ++/*** ++quick decrypt ++ ++@function decrypt ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam string input data to decrypt ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn string result decrypt data ++*/ + static LUA_FUNCTION(openssl_evp_decrypt) + { + const EVP_CIPHER* cipher; +@@ -193,6 +233,19 @@ static LUA_FUNCTION(openssl_evp_decrypt) + return 0; + } + ++/*** ++quick encrypt or decrypt ++ ++@function cipher ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam boolean encrypt true for encrypt,false for decrypt ++@tparam string input data to encrypt or decrypt ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn string result ++*/ + static LUA_FUNCTION(openssl_evp_cipher) + { + const EVP_CIPHER* cipher = NULL; +@@ -285,6 +338,21 @@ typedef enum + DO_DECRYPT = 1 + } CIPHER_MODE; + ++/*** ++get evp_cipher_ctx object for encrypt or decrypt ++ ++@function new ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam boolean encrypt true for encrypt,false for decrypt ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn evp_cipher_ctx cipher object mapping EVP_CIPHER_CTX in openssl ++ ++@see evp_cipher_ctx ++*/ ++ + static LUA_FUNCTION(openssl_cipher_new) + { + const EVP_CIPHER* cipher = get_cipher(L, 1, NULL); +@@ -328,6 +396,20 @@ static LUA_FUNCTION(openssl_cipher_new) + return 1; + } + ++/*** ++get evp_cipher_ctx object for encrypt ++ ++@function encrypt_new ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn evp_cipher_ctx cipher object mapping EVP_CIPHER_CTX in openssl ++ ++@see evp_cipher_ctx ++*/ ++ + static LUA_FUNCTION(openssl_cipher_encrypt_new) + { + const EVP_CIPHER* cipher = get_cipher(L, 1, NULL); +@@ -370,6 +452,20 @@ static LUA_FUNCTION(openssl_cipher_encry + return 1; + } + ++/*** ++get evp_cipher_ctx object for decrypt ++ ++@function decrypt_new ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn evp_cipher_ctx cipher object mapping EVP_CIPHER_CTX in openssl ++ ++@see evp_cipher_ctx ++*/ ++ + static LUA_FUNCTION(openssl_cipher_decrypt_new) + { + const EVP_CIPHER* cipher = get_cipher(L, 1, NULL); +@@ -424,7 +520,16 @@ static LUA_FUNCTION(openssl_cipher_decry + return 0; + } + +-/* evp_cipher method */ ++/*** ++openssl.evp_cipher object ++@type evp_cipher ++*/ ++/*** ++get infomation of evp_cipher object ++ ++@function info ++@treturn table info keys include name,block_size,key_length,iv_length,flags,mode ++*/ + static LUA_FUNCTION(openssl_cipher_info) + { + EVP_CIPHER *cipher = CHECK_OBJECT(1, EVP_CIPHER, "openssl.evp_cipher"); +@@ -438,14 +543,23 @@ static LUA_FUNCTION(openssl_cipher_info) + return 1; + } + ++/*** ++derive key + ++@function BytesToKey ++@tparam string data derive data ++@tparam string[opt] string salt salt will get strong security ++@tparam ev_digest|string md digest method used to diver key, default with 'sha1' ++@treturn string key ++@treturn string iv ++*/ + static LUA_FUNCTION(openssl_evp_BytesToKey) + { + EVP_CIPHER* c = CHECK_OBJECT(1, EVP_CIPHER, "openssl.evp_cipher"); + size_t lsalt, lk; + const char* k = luaL_checklstring(L, 2, &lk); + const char* salt = luaL_optlstring(L, 3, NULL, &lsalt); +- const EVP_MD* m = lua_isnoneornil(L, 4) ? EVP_get_digestbyname("sha1") : get_digest(L, 4); ++ const EVP_MD* m = get_digest(L, 4, "sha256"); + char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + int ret; + if (salt != NULL && lsalt < PKCS5_SALT_LEN) +@@ -457,15 +571,102 @@ static LUA_FUNCTION(openssl_evp_BytesToK + ret = EVP_BytesToKey(c, m, (unsigned char*)salt, (unsigned char*)k, lk, 1, (unsigned char*)key, (unsigned char*)iv); + if (ret > 1) + { +- lua_pushlstring(L, key, c->key_len); +- lua_pushlstring(L, iv, c->iv_len); ++ lua_pushlstring(L, key, EVP_CIPHER_key_length(c)); ++ lua_pushlstring(L, iv, EVP_CIPHER_iv_length(c)); + return 2; + } + return openssl_pushresult(L, ret); + } + ++/*** ++get evp_cipher_ctx to encrypt or decrypt ++ ++@function new ++@tparam boolean encrypt true for encrypt,false for decrypt ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn evp_cipher_ctx evp_cipher_ctx object ++ ++@see evp_cipher_ctx ++*/ ++ ++/*** ++get evp_cipher_ctx to encrypt ++ ++@function encrypt_new ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn evp_cipher_ctx evp_cipher_ctx object ++ ++@see evp_cipher_ctx ++*/ ++ ++/*** ++get evp_cipher_ctx to decrypt ++ ++@function decrypt_new ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn evp_cipher_ctx evp_cipher_ctx object ++ ++@see evp_cipher_ctx ++*/ ++ ++/*** ++do encrypt or decrypt ++ ++@function cipher ++@tparam boolean encrypt true for encrypt,false for decrypt ++@tparam string input data to encrypt or decrypt ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn string result ++*/ ++ ++/*** ++do encrypt ++ ++@function encrypt ++@tparam string input data to encrypt ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn string result ++*/ ++ ++/*** ++do decrypt ++ ++@function decrypt ++@tparam string input data to decrypt ++@tparam string key secret key ++@tparam[opt] string iv ++@tparam[opt] boolean pad true for padding default ++@tparam[opt] engine engine custom crypto engine ++@treturn string result ++*/ + + /* evp_cipher_ctx method */ ++/*** ++openssl.evp_cipher_ctx object ++@type evp_cipher_ctx ++*/ ++/*** ++feed data to do cipher ++ ++@function update ++@tparam string msg data ++@treturn string result parture result ++*/ + static LUA_FUNCTION(openssl_evp_cipher_update) + { + EVP_CIPHER_CTX* c = CHECK_OBJECT(1, EVP_CIPHER_CTX, "openssl.evp_cipher_ctx"); +@@ -498,6 +699,12 @@ static LUA_FUNCTION(openssl_evp_cipher_u + return (ret == 1 ? ret : openssl_pushresult(L, ret)); + } + ++/*** ++get result of cipher ++ ++@function final ++@treturn string result last result ++*/ + static LUA_FUNCTION(openssl_evp_cipher_final) + { + EVP_CIPHER_CTX* c = CHECK_OBJECT(1, EVP_CIPHER_CTX, "openssl.evp_cipher_ctx"); +@@ -527,6 +734,12 @@ static LUA_FUNCTION(openssl_evp_cipher_f + return openssl_pushresult(L, ret); + } + ++/*** ++get infomation of evp_cipher_ctx object ++ ++@function info ++@treturn table info keys include block_size,key_length,iv_length,flags,mode,nid,type, evp_cipher ++*/ + static LUA_FUNCTION(openssl_cipher_ctx_info) + { + EVP_CIPHER_CTX *ctx = CHECK_OBJECT(1, EVP_CIPHER_CTX, "openssl.evp_cipher_ctx"); +@@ -546,10 +759,13 @@ static LUA_FUNCTION(openssl_cipher_ctx_i + static LUA_FUNCTION(openssl_cipher_ctx_free) + { + EVP_CIPHER_CTX *ctx = CHECK_OBJECT(1, EVP_CIPHER_CTX, "openssl.evp_cipher_ctx"); ++ if(!ctx) ++ return 0; + lua_pushnil(L); + lua_rawsetp(L, LUA_REGISTRYINDEX, ctx); + EVP_CIPHER_CTX_cleanup(ctx); + EVP_CIPHER_CTX_free(ctx); ++ FREE_OBJECT(1); + return 0; + } + +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/cms.c luvi-src-v2.7.6/deps/lua-openssl/src/cms.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/cms.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/cms.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,10 +1,32 @@ +-/*=========================================================================*\ +-* hamc.c +-* hamc module for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++cms module for lua-openssl binding + ++The Cryptographic Message Syntax (CMS) is the IETF's standard for ++cryptographically protected messages. It can be used to digitally sign, digest, ++authenticate or encrypt any form of digital data. CMS is based on the syntax of ++PKCS#7, which in turn is based on the Privacy-Enhanced Mail standard. The ++newest version of CMS is specified in RFC 5652. ++ ++The architecture of CMS is built around certificate-based key management, such ++as the profile defined by the PKIX working group. CMS is used as the key ++cryptographic component of many other cryptographic standards, such as S/MIME, ++PKCS #12 and the RFC 3161 Digital timestamping protocol. ++ ++OpenSSL is open source software that can encrypt, decrypt, sign and verify, ++compress and uncompress CMS documents. ++ ++ ++CMS are based on apps/cms.c from the OpenSSL dist, so for more information, ++you better see the documentation for OpenSSL. ++cms api need flags, not support "detached", "nodetached", "text", "nointern", ++"noverify", "nochain", "nocerts", "noattr", "binary", "nosigs" ++ ++OpenSSL not give full document about CMS api, so some function will be dangers. ++ ++@module cms ++@usage ++ cms = require('openssl').cms ++*/ + #include "openssl.h" + #include "private.h" + #if OPENSSL_VERSION_NUMBER > 0x00909000L && !defined (LIBRESSL_VERSION_NUMBER) +@@ -14,35 +36,47 @@ + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + +-static LuaL_Enum cms_flags[] = ++static LuaL_Enumeration cms_flags[] = + { +- {"text", 0x1}, +- {"nocerts", 0x2}, +- {"no_content_verify", 0x04}, +- {"no_attr_verify", 0x8}, +- {"nosigs", (CMS_NO_CONTENT_VERIFY | CMS_NO_ATTR_VERIFY)}, +- {"nointern", 0x10}, ++ {"text", 0x1}, ++ {"nocerts", 0x2}, ++ {"no_content_verify", 0x04}, ++ {"no_attr_verify", 0x8}, ++ {"nosigs", (CMS_NO_CONTENT_VERIFY | CMS_NO_ATTR_VERIFY)}, ++ {"nointern", 0x10}, + {"no_signer_cert_verify", 0x20}, +- {"noverify", 0x20}, +- {"detached", 0x40}, +- {"binary", 0x80}, +- {"noattr", 0x100}, +- {"nosmimecap", 0x200}, +- {"nooldmimetype", 0x400}, +- {"crlfeol", 0x800}, +- {"stream", 0x1000}, +- {"nocrl", 0x2000}, +- {"partial", 0x4000}, +- {"reuse_digest", 0x8000}, +- {"use_keyid", 0x10000}, +- {"debug_decrypt", 0x20000}, +- {NULL, -1} ++ {"noverify", 0x20}, ++ {"detached", 0x40}, ++ {"binary", 0x80}, ++ {"noattr", 0x100}, ++ {"nosmimecap", 0x200}, ++ {"nooldmimetype", 0x400}, ++ {"crlfeol", 0x800}, ++ {"stream", 0x1000}, ++ {"nocrl", 0x2000}, ++ {"partial", 0x4000}, ++ {"reuse_digest", 0x8000}, ++ {"use_keyid", 0x10000}, ++ {"debug_decrypt", 0x20000}, ++ {NULL, -1} + }; + ++/*** ++read cms object from input bio or string ++ ++@function read ++@tparam bio|string input ++@tparam[opt='auto'] string format, support 'auto','smime','der','pem' ++ auto will only try 'der' or 'pem' ++@tparam[opt=nil] bio content, only used when format is 'smime' ++@treturn cms ++*/ + static int openssl_cms_read(lua_State *L) + { + BIO* in = load_bio_object(L, 1); + int fmt = luaL_checkoption(L, 2, "auto", format); ++ BIO* data = NULL; ++ + CMS_ContentInfo *cms = NULL; + if (fmt == FORMAT_AUTO) + { +@@ -60,27 +94,38 @@ static int openssl_cms_read(lua_State *L + } + else if (fmt == FORMAT_SMIME) + { +- BIO *indata = load_bio_object(L, 3); +- cms = SMIME_read_CMS(in, &indata); ++ cms = SMIME_read_CMS(in, &data); + } + + if (cms) + { + PUSH_OBJECT(cms, "openssl.cms"); +- return 1; ++ if(data!=NULL) ++ PUSH_OBJECT(data, "openssl.bn"); ++ return data!=NULL? 2 : 1; + } + return openssl_pushresult(L, 0); + } + ++/*** ++write cms object to bio object + ++@function export ++@tparam cms cms ++@tparam[opt] bio data ++@tparam[opt=0] number flags ++@tparam[opt='smime'] string format ++@treturn string ++@return nil, and followed by error message ++*/ + static int openssl_cms_write(lua_State *L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); +- BIO *out = load_bio_object(L, 2); +- BIO *in = load_bio_object(L, 3); +- int flags = luaL_optint(L, 4, 0); +- int fmt = luaL_checkoption(L, 5, "smime", format); ++ BIO *in = lua_isnoneornil(L, 2) ? NULL : load_bio_object(L, 2); ++ int flags = luaL_optint(L, 3, 0); ++ int fmt = luaL_checkoption(L, 4, "smime", format); + int ret = 0; ++ BIO *out = BIO_new(BIO_s_mem()); + + if (fmt == FORMAT_SMIME) + ret = SMIME_write_CMS(out, cms, in, flags); +@@ -89,13 +134,45 @@ static int openssl_cms_write(lua_State * + else if (fmt == FORMAT_DER) + { + ret = i2d_CMS_bio_stream(out, cms, in, flags); +- //i2d_CMS_bio + } + else + luaL_argerror(L, 5, "only accept smime, pem or der"); ++ if (ret==1) ++ { ++ BUF_MEM *mem; ++ BIO_get_mem_ptr(out, &mem); ++ lua_pushlstring(L, mem->data, mem->length); ++ } ++ if(in!=NULL) ++ BIO_free(in); ++ if(out!=NULL) ++ BIO_free(out); ++ if(ret==1) ++ return 1; + return openssl_pushresult(L, ret); + } +- ++/*** ++create empty cms object ++@function create ++@treturn cms ++*/ ++ ++/*** ++create cms object from string or bio object ++@function create ++@tparam bio input ++@tparam[opt=0] number flags ++@treturn cms ++*/ ++ ++/*** ++create digest cms object ++@function create ++@tparam bio input ++@tparam evp_digest|string md_alg ++@tparam[opt=0] number flags ++@treturn cms ++*/ + static int openssl_cms_create(lua_State*L) + { + CMS_ContentInfo *cms = NULL; +@@ -109,7 +186,7 @@ static int openssl_cms_create(lua_State* + BIO* in = load_bio_object(L, 1); + if (lua_isuserdata(L, 2)) + { +- const EVP_MD* md = get_digest(L, 2); ++ const EVP_MD* md = get_digest(L, 2, NULL); + int flags = luaL_optint(L, 3, 0); + cms = CMS_digest_create(in, md, flags); + } +@@ -124,7 +201,14 @@ static int openssl_cms_create(lua_State* + return 1; + } + +- ++/*** ++create compress cms object ++@function compress ++@tparam bio input ++@tparam string alg, zlib or rle ++@tparam[opt=0] number flags ++@treturn cms ++*/ + static int openssl_cms_compress(lua_State *L) + { + BIO* in = load_bio_object(L, 1); +@@ -150,6 +234,15 @@ static int openssl_cms_compress(lua_Stat + return openssl_pushresult(L, 0); + } + ++/*** ++uncompress cms object ++@function uncompress ++@tparam cms cms ++@tparam bio input ++@tparam bio out ++@tparam[opt=0] number flags ++@treturn boolean ++*/ + static int openssl_cms_uncompress(lua_State *L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); +@@ -161,15 +254,26 @@ static int openssl_cms_uncompress(lua_St + return openssl_pushresult(L, ret); + } + ++/*** ++make signed cms object ++ ++@function sign ++@tparam x509 signer cert ++@tparam evp_pkey pkey ++@tparam bio input_data ++@tparam[opt] stack_of_x509 certs include in the CMS ++@tparam[opt=0] number flags ++@treturn cms object ++*/ + static int openssl_cms_sign(lua_State *L) + { + X509* signcert = CHECK_OBJECT(1, X509, "openssl.x509"); + EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); +- STACK_OF(X509)* certs = openssl_sk_x509_fromtable(L, 3); +- BIO* data = load_bio_object(L, 4); ++ BIO* data = load_bio_object(L, 3); ++ STACK_OF(X509)* certs = openssl_sk_x509_fromtable(L, 4); + unsigned int flags = luaL_optint(L, 5, 0); + CMS_ContentInfo *cms; +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 2, "must be private key"); ++ + cms = CMS_sign(signcert, pkey, certs, data, flags); + if (cms) + { +@@ -179,59 +283,62 @@ static int openssl_cms_sign(lua_State *L + return openssl_pushresult(L, 0); + } + ++ ++/*** ++verfiy signed cms object ++@function verify ++@tparam cms signed ++@tparam stack_of_x509 signers ++@tparam[opt] x509_store store trust certificates store ++@tparam[opt] bio message ++@tparam[opt=0] number flags ++@treturn string content ++@return nil, and followed by error message ++*/ + static int openssl_cms_verify(lua_State *L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); +- static const char* verify_mode[] = +- { +- "verify", /* 0 */ +- "digest", /* 1 */ +- "receipt", /* 2 */ +- NULL +- }; +- int mode = luaL_checkoption(L, 2, NULL, verify_mode); +- if (mode == 1) +- { +- BIO* in = load_bio_object(L, 3); +- BIO* out = load_bio_object(L, 4); +- unsigned int flags = luaL_optint(L, 5, 0); +- +- int ret = CMS_digest_verify(cms, in, out, flags); +- return openssl_pushresult(L, ret); +- } +- if (mode == 2) +- { +- CMS_ContentInfo *src = CHECK_OBJECT(3, CMS_ContentInfo, "openssl.cms"); +- STACK_OF(X509) *other = openssl_sk_x509_fromtable(L, 4); +- X509_STORE* store = CHECK_OBJECT(5, X509_STORE, "openssl.x509_store"); +- unsigned int flags = luaL_optint(L, 6, 0); +- int ret = CMS_verify_receipt(cms, src, other, store, flags); +- return openssl_pushresult(L, ret); +- } +- if (mode == 0) +- { +- STACK_OF(X509) *other = openssl_sk_x509_fromtable(L, 3); +- X509_STORE* store = CHECK_OBJECT(4, X509_STORE, "openssl.x509_store"); +- BIO* in = load_bio_object(L, 5); +- BIO* out = load_bio_object(L, 6); +- unsigned int flags = luaL_optint(L, 7, 0); +- int ret = CMS_verify(cms, other, store, in, out, flags); +- return openssl_pushresult(L, ret); +- } +- +- return 0; +-} +- +- ++ STACK_OF(X509)* signers = openssl_sk_x509_fromtable(L, 2); ++ X509_STORE* trust = CHECK_OBJECT(3, X509_STORE, "openssl.x509_store"); ++ BIO* in = lua_isnoneornil(L, 4) ? NULL : load_bio_object(L, 4); ++ unsigned int flags = luaL_optint(L, 5, 0); ++ BIO* out = BIO_new(BIO_s_mem()); ++ int ret = CMS_verify(cms, signers, trust, in, out, flags); ++ if (ret==1) ++ { ++ BUF_MEM *mem; ++ BIO_get_mem_ptr(out, &mem); ++ lua_pushlstring(L, mem->data, mem->length); ++ } ++ if (in!=NULL) ++ BIO_free(in); ++ if (out!=NULL) ++ BIO_free(out); ++ if (ret !=1) ++ ret = openssl_pushresult(L, ret); ++ return ret; ++} ++ ++/*** ++create enryptdata cms ++@function EncryptedData_encrypt ++@tparam bio|string input ++@tparam strig key ++@tparam[opt='des-ede3-cbc'] string|evp_cipher cipher_alg ++@tparam[opt=0] number flags ++@treturn cms object ++@return nil, followed by error message ++*/ + static int openssl_cms_EncryptedData_encrypt(lua_State*L) + { + BIO* in = load_bio_object(L, 1); +- const EVP_CIPHER* ciphers = get_cipher(L, 2, NULL); + size_t klen; +- const char* key = luaL_checklstring(L, 3, &klen); ++ const char* key = luaL_checklstring(L, 2, &klen); ++ const EVP_CIPHER* ciphers = get_cipher(L, 3, "des-ede3-cbc"); + unsigned int flags = luaL_optint(L, 4, 0); + + CMS_ContentInfo *cms = CMS_EncryptedData_encrypt(in, ciphers, (const unsigned char*) key, klen, flags); ++ BIO_free(in); + if (cms) + { + PUSH_OBJECT(cms, "openssl.cms"); +@@ -240,18 +347,92 @@ static int openssl_cms_EncryptedData_enc + return openssl_pushresult(L, 0); + } + ++/*** ++decrypt encryptdata cms ++@function EncryptedData_decrypt ++@tparam cms encrypted ++@tparam string key ++@tparam[opt] bio dcont ++@tparam[opt=0] number flags ++@treturn boolean result ++*/ + static int openssl_cms_EncryptedData_decrypt(lua_State*L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); + size_t klen; + const char* key = luaL_checklstring(L, 2, &klen); +- BIO* dcont = load_bio_object(L, 3); +- BIO* out = load_bio_object(L, 4); +- unsigned int flags = luaL_optint(L, 5, 0); ++ BIO* dcont = lua_isnoneornil(L, 3) ? NULL : load_bio_object(L, 3); ++ unsigned int flags = luaL_optint(L, 4, 0); ++ BIO *out = BIO_new(BIO_s_mem()); + + int ret = CMS_EncryptedData_decrypt(cms, (const unsigned char*)key, klen, dcont, out, flags); ++ if(ret==1) ++ { ++ BUF_MEM *mem; ++ BIO_get_mem_ptr(out, &mem); ++ lua_pushlstring(L, mem->data, mem->length); ++ } ++ if(dcont!=NULL) ++ BIO_free(dcont); ++ BIO_free(out); ++ if(ret!=1) ++ ret = openssl_pushresult(L, ret); ++ return ret; ++} ++ ++/*** ++create digest cms ++@function digest_create ++@tparam bio|string input ++@tparam[opt='sha256'] string|evp_md digest_alg ++@tparam[opt=0] number flags ++@treturn cms object ++@return nil, followed by error message ++*/ ++static int openssl_cms_digest_create(lua_State*L) ++{ ++ BIO* in = load_bio_object(L, 1); ++ const EVP_MD* md = get_digest(L, 2, "sha256"); ++ unsigned int flags = luaL_optint(L, 3, 0); + +- return openssl_pushresult(L, ret); ++ CMS_ContentInfo *cms = CMS_digest_create(in, md, flags); ++ BIO_free(in); ++ if (cms) ++ { ++ PUSH_OBJECT(cms, "openssl.cms"); ++ return 1; ++ } ++ return openssl_pushresult(L, 0); ++} ++ ++/*** ++verify digest cms ++@function digest_verify ++@tparam cms digested ++@tparam[opt] string|bio dcont ++@tparam[opt=0] number flags ++@treturn boolean result ++*/ ++static int openssl_cms_digest_verify(lua_State*L) ++{ ++ CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); ++ BIO *dcont = lua_isnoneornil(L, 2) ? NULL : load_bio_object(L, 2); ++ unsigned int flags = luaL_optint(L, 3, 0); ++ BIO *out = BIO_new(BIO_s_mem()); ++ ++ int ret = CMS_digest_verify(cms, dcont, out, flags); ++ if(ret==1) ++ { ++ BUF_MEM *mem; ++ BIO_get_mem_ptr(out, &mem); ++ lua_pushlstring(L, mem->data, mem->length); ++ } ++ if(dcont!=NULL) ++ BIO_free(dcont); ++ BIO_free(out); ++ if(ret!=1) ++ ret = openssl_pushresult(L, ret); ++ return ret; + } + + static char *memdup(const char *src, size_t buffer_length) +@@ -284,19 +465,31 @@ static char *memdup(const char *src, siz + return buffer; + } + ++/*** ++encrypt with recipt certs ++@function encrypt ++@tparam stack_of_x509 recipt certs ++@tparam bio|string input ++@tparam[opt='des-ede3-cbc'] string|evp_cipher cipher_alg ++@tparam[opt=0] number flags ++@tparam[opt=nil] table options, support key, keyid, password fields, ++ and values must be string type ++@treturn cms ++*/ + static int openssl_cms_encrypt(lua_State *L) + { + STACK_OF(X509)* encerts = openssl_sk_x509_fromtable(L, 1); + BIO* in = load_bio_object(L, 2); +- const EVP_CIPHER* ciphers = get_cipher(L, 3, NULL); ++ const EVP_CIPHER* ciphers = get_cipher(L, 3, "des-ede3-cbc"); + unsigned int flags = luaL_optint(L, 4, 0); +- int ret = 0; + CMS_ContentInfo *cms = CMS_encrypt(encerts, in, ciphers, flags); +- CMS_RecipientInfo *recipient; ++ int ret = 1; + if (cms) + { + if (lua_istable(L, 5)) + { ++ CMS_RecipientInfo *recipient; ++ + lua_getfield(L, 5, "key"); + lua_getfield(L, 5, "keyid"); + if (lua_isstring(L, -1) && lua_isstring(L, -2)) +@@ -358,19 +551,32 @@ static int openssl_cms_encrypt(lua_State + return openssl_pushresult(L, ret); + } + ++/*** ++decrypt cms message ++@function decrypt ++@tparam cms message ++@tparam evp_pkey pkey ++@tparam x509 recipt ++@tparam[opt] bio dcount output object ++@tparam[opt=0] number flags ++@tparam[opt=nil] table options may have key, keyid, password field, ++ and values must be string type ++@treturn string decrypted message ++@return nil, and followed by error message ++*/ + static int openssl_cms_decrypt(lua_State *L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); + EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); + X509* x509 = CHECK_OBJECT(3, X509, "openssl.x509"); +- BIO* dcont = load_bio_object(L, 4); +- BIO* out = load_bio_object(L, 5); +- unsigned int flags = luaL_optint(L, 6, 0); ++ BIO* dcont = lua_isnoneornil(L, 4) ? NULL : load_bio_object(L, 4); ++ unsigned int flags = luaL_optint(L, 5, 0); + int ret = 1; ++ BIO* out = BIO_new(BIO_s_mem()); + +- if (lua_istable(L, 7)) ++ if (lua_istable(L, 6)) + { +- lua_getfield(L, 7, "password"); ++ lua_getfield(L, 6, "password"); + if (lua_isstring(L, -1)) + { + unsigned char*passwd = (unsigned char*)lua_tostring(L, -1); +@@ -383,8 +589,8 @@ static int openssl_cms_decrypt(lua_State + lua_pop(L, 1); + if (ret) + { +- lua_getfield(L, 7, "key"); +- lua_getfield(L, 7, "keyid"); ++ lua_getfield(L, 6, "key"); ++ lua_getfield(L, 6, "keyid"); + if (lua_isstring(L, -1) && lua_isstring(L, -2)) + { + size_t keylen, keyidlen; +@@ -394,30 +600,32 @@ static int openssl_cms_decrypt(lua_State + } + else if (!lua_isnil(L, -1) || !lua_isnil(L, -2)) + { +- luaL_argerror(L, 7, "key and keyid field must be string"); ++ luaL_argerror(L, 6, "key and keyid field must be string"); + } + lua_pop(L, 2); + } + } + + if (ret) +- { + ret = CMS_decrypt_set1_pkey(cms, pkey, x509); +- } + + if (ret == 1) + ret = CMS_decrypt(cms, NULL, NULL, dcont, out, flags); +- return openssl_pushresult(L, ret); +-} + ++ if (ret == 1) ++ { ++ BUF_MEM *mem; ++ BIO_get_mem_ptr(out, &mem); ++ lua_pushlstring(L, mem->data, mem->length); ++ } + +-/************************************************************************/ +-static int openssl_cms_type(lua_State *L) +-{ +- CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); +- const ASN1_OBJECT *obj = CMS_get0_type(cms); +- PUSH_OBJECT(obj, "openssl.object"); ++ if (dcont!=NULL) ++ BIO_free(dcont); ++ if (out!=NULL) ++ BIO_free(out); + ++ if (ret!=1) ++ return openssl_pushresult(L, ret); + return 1; + } + +@@ -430,24 +638,103 @@ static int openssl_cms_bio_new(lua_State + return 1; + } + ++static const luaL_Reg R[] = ++{ ++ {"read", openssl_cms_read}, ++ {"write", openssl_cms_write}, ++ ++ {"bio_new", openssl_cms_bio_new}, ++ {"create", openssl_cms_create}, ++ ++ {"sign", openssl_cms_sign}, ++ {"verify", openssl_cms_verify}, ++ {"encrypt", openssl_cms_encrypt}, ++ {"decrypt", openssl_cms_decrypt}, ++ ++ {"digest_create", openssl_cms_digest_create}, ++ {"digest_verify", openssl_cms_digest_verify}, ++ {"EncryptedData_encrypt", openssl_cms_EncryptedData_encrypt}, ++ {"EncryptedData_decrypt", openssl_cms_EncryptedData_decrypt}, ++ {"compress", openssl_cms_compress}, ++ {"uncompress", openssl_cms_uncompress}, ++ ++ {NULL, NULL} ++}; ++ ++/*****************************************************************************/ ++/*** ++openssl.cms object ++@type cms ++@warning some api undocumented, dangers!!! ++*/ ++ ++/*** ++get type of cms object ++@function cms ++@treturn asn1_object type of cms ++*/ ++static int openssl_cms_type(lua_State *L) ++{ ++ CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); ++ const ASN1_OBJECT *obj = CMS_get0_type(cms); ++ PUSH_OBJECT(obj, "openssl.asn1_object"); ++ ++ return 1; ++} ++ ++/*** ++do dataInit ++@function datainit ++@tparam[opt] bio|string data ++@treturn bio cmsbio ++@return nil for fail ++@warning inner use ++*/ + static int openssl_cms_datainit(lua_State *L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); +- BIO* icont = load_bio_object(L, 2); +- icont = CMS_dataInit(cms, icont); +- PUSH_OBJECT(icont, "openssl.bio"); ++ BIO* icont = lua_isnoneornil(L, 2) ? NULL : load_bio_object(L, 2); ++ BIO* cbio = CMS_dataInit(cms, icont); ++ if(cbio!=NULL) ++ PUSH_OBJECT(icont, "openssl.bio"); ++ else ++ lua_pushnil(L); ++ BIO_free(icont); + return 1; + } + ++/*** ++do dataFinal ++@function datafnal ++@tparam bio cmsbio bio returned by datainit ++@treturn boolean true for success, other value will followed by error message ++@warning inner use ++*/ + static int openssl_cms_datafinal(lua_State *L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); + BIO* bio = load_bio_object(L, 2); + int ret = CMS_dataFinal(cms, bio); + lua_pushboolean(L, ret); ++ BIO_free(bio); + return 1; + } + ++/*** ++get detached state ++@function detached ++@treturn boolean true for detached ++@tparam bio cmsbio bio returned by datainit ++@treturn boolean true for success, others value will followed by error message ++@warning inner use ++*/ ++/*** ++set detached state ++@function detached ++@tparam boolean detach ++@treturn boolean for success, others value will followed by error message ++@warning inner use ++*/ + static int openssl_cms_detached(lua_State *L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); +@@ -455,29 +742,37 @@ static int openssl_cms_detached(lua_Stat + if (lua_isnone(L, 2)) + { + ret = CMS_is_detached(cms); ++ lua_pushboolean(L, ret); ++ return 1; + } + else + { + int detached = auxiliar_checkboolean(L, 2); + ret = CMS_set_detached(cms, detached); + } +- lua_pushboolean(L, ret); + return 1; + } + ++/*** ++get content of cms object ++@function content ++@treturn string content, if have no content will return nil ++@warning inner use ++*/ + static int openssl_cms_content(lua_State *L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); + ASN1_OCTET_STRING** content = CMS_get0_content(cms); + if (content && *content) + { +- +- lua_pushnil(L); +- return 1; ++ ASN1_OCTET_STRING* s = *content; ++ lua_pushlstring(L, (const char*)ASN1_STRING_data(s), ASN1_STRING_length(s)); + } +- lua_pushnil(L); ++ else ++ lua_pushnil(L); + return 1; + } ++ + static int openssl_cms_get_signers(lua_State*L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); +@@ -489,6 +784,7 @@ static int openssl_cms_get_signers(lua_S + } + return 0; + } ++ + static int openssl_cms_data(lua_State *L) + { + CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); +@@ -541,47 +837,26 @@ static int openssl_cms_free(lua_State *L + + static luaL_Reg cms_ctx_funs[] = + { +- {"type", openssl_cms_type}, +- {"datainit", openssl_cms_datainit}, +- {"datafinal", openssl_cms_datafinal}, +- {"content", openssl_cms_content}, +- {"data", openssl_cms_data}, +- {"signers", openssl_cms_get_signers}, +- +- {"detached", openssl_cms_detached}, +- +- { "sign_receipt", openssl_cms_sign_receipt}, +- { "get_signers", openssl_cms_get_signers}, +- +- { "bio_new", openssl_cms_bio_new}, +- +- {"final", openssl_cms_final}, +- {"__tostring", auxiliar_tostring}, +- {"__gc", openssl_cms_free}, +- {NULL, NULL} ++ {"type", openssl_cms_type}, ++ {"datainit", openssl_cms_datainit}, ++ {"datafinal", openssl_cms_datafinal}, ++ {"content", openssl_cms_content}, ++ {"data", openssl_cms_data}, ++ {"signers", openssl_cms_get_signers}, ++ {"detached", openssl_cms_detached}, ++ ++ {"sign_receipt", openssl_cms_sign_receipt}, ++ {"get_signers", openssl_cms_get_signers}, ++ ++ {"bio_new", openssl_cms_bio_new}, ++ {"final", openssl_cms_final}, ++ ++ {"__tostring", auxiliar_tostring}, ++ {"__gc", openssl_cms_free}, ++ {NULL, NULL} + }; + + /* int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); */ +-static const luaL_Reg R[] = +-{ +- { "read", openssl_cms_read}, +- { "write", openssl_cms_write}, +- +- { "bio_new", openssl_cms_bio_new}, +- { "create", openssl_cms_create}, +- +- { "sign", openssl_cms_sign}, +- { "verify", openssl_cms_verify}, +- { "encrypt", openssl_cms_encrypt}, +- { "decrypt", openssl_cms_decrypt}, +- +- { "EncryptedData_encrypt", openssl_cms_EncryptedData_encrypt}, +- { "EncryptedData_decrypt", openssl_cms_EncryptedData_decrypt}, +- { "compress", openssl_cms_compress}, +- { "uncompress", openssl_cms_uncompress}, +- +- {NULL, NULL} +-}; + #endif + + int luaopen_cms(lua_State *L) +@@ -593,9 +868,11 @@ int luaopen_cms(lua_State *L) + + lua_newtable(L); + luaL_setfuncs(L, R, 0); +- lua_pushliteral(L, "version"); /** version */ ++ lua_pushliteral(L, "version"); + lua_pushliteral(L, MYVERSION); + lua_settable(L, -3); ++ ++ auxiliar_enumerate(L, -1, cms_flags); + #else + lua_pushnil(L); + #endif +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/compat.c luvi-src-v2.7.6/deps/lua-openssl/src/compat.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/compat.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/compat.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,7 +1,533 @@ +- + #include + #include + #include + ++#include "openssl.h" ++#include "private.h" ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++int BIO_up_ref(BIO *b) ++{ ++ CRYPTO_add(&b->references, 1, CRYPTO_LOCK_BIO); ++ return 1; ++} ++int X509_up_ref(X509 *x) ++{ ++ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); ++ return 1; ++} ++int X509_STORE_up_ref(X509_STORE *s) ++{ ++ CRYPTO_add(&s->references, 1, CRYPTO_LOCK_X509_STORE); ++ return 1; ++} ++int EVP_PKEY_up_ref(EVP_PKEY *pkey) ++{ ++ CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); ++ return 1; ++} ++ ++int RSA_bits(const RSA *r) ++{ ++ return (BN_num_bits(r->n)); ++} ++ ++void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) ++{ ++ *pr = sig->r; ++ *ps = sig->s; ++} ++int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) ++{ ++ if (r == NULL || s == NULL) ++ return 0; ++ BN_free(sig->r); ++ BN_free(sig->s); ++ sig->r = r; ++ sig->s = s; ++ return 1; ++} ++void RSA_get0_key(const RSA *r, ++ const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) ++{ ++ if (n != NULL) ++ *n = r->n; ++ if (e != NULL) ++ *e = r->e; ++ if (d != NULL) ++ *d = r->d; ++} ++ ++void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) ++{ ++ if (p != NULL) ++ *p = r->p; ++ if (q != NULL) ++ *q = r->q; ++} ++ ++void RSA_get0_crt_params(const RSA *r, ++ const BIGNUM **dmp1, const BIGNUM **dmq1, ++ const BIGNUM **iqmp) ++{ ++ if (dmp1 != NULL) ++ *dmp1 = r->dmp1; ++ if (dmq1 != NULL) ++ *dmq1 = r->dmq1; ++ if (iqmp != NULL) ++ *iqmp = r->iqmp; ++} ++ ++HMAC_CTX *HMAC_CTX_new(void) ++{ ++ HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); ++ ++ if (ctx != NULL) ++ { ++ HMAC_CTX_init(ctx); ++ } ++ return ctx; ++} ++ ++void HMAC_CTX_free(HMAC_CTX *ctx) ++{ ++ if (ctx != NULL) ++ { ++ HMAC_CTX_cleanup(ctx); ++ OPENSSL_free(ctx); ++ } ++} ++ ++#ifndef OPENSSL_NO_DSA ++DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) ++{ ++ if (pkey->type != EVP_PKEY_DSA) ++ { ++ return NULL; ++ } ++ return pkey->pkey.dsa; ++} ++ ++int DSA_bits(const DSA *dsa) ++{ ++ return BN_num_bits(dsa->p); ++} ++ ++void DSA_get0_pqg(const DSA *d, ++ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) ++{ ++ if (p != NULL) ++ *p = d->p; ++ if (q != NULL) ++ *q = d->q; ++ if (g != NULL) ++ *g = d->g; ++} ++ ++int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) ++{ ++ /* If the fields p, q and g in d are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((d->p == NULL && p == NULL) ++ || (d->q == NULL && q == NULL) ++ || (d->g == NULL && g == NULL)) ++ return 0; ++ ++ if (p != NULL) ++ { ++ BN_free(d->p); ++ d->p = p; ++ } ++ if (q != NULL) ++ { ++ BN_free(d->q); ++ d->q = q; ++ } ++ if (g != NULL) ++ { ++ BN_free(d->g); ++ d->g = g; ++ } ++ ++ return 1; ++} ++ ++void DSA_get0_key(const DSA *d, ++ const BIGNUM **pub_key, const BIGNUM **priv_key) ++{ ++ if (pub_key != NULL) ++ *pub_key = d->pub_key; ++ if (priv_key != NULL) ++ *priv_key = d->priv_key; ++} ++ ++int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) ++{ ++ /* If the field pub_key in d is NULL, the corresponding input ++ * parameters MUST be non-NULL. The priv_key field may ++ * be left NULL. ++ */ ++ if (d->pub_key == NULL && pub_key == NULL) ++ return 0; ++ ++ if (pub_key != NULL) ++ { ++ BN_free(d->pub_key); ++ d->pub_key = pub_key; ++ } ++ if (priv_key != NULL) ++ { ++ BN_free(d->priv_key); ++ d->priv_key = priv_key; ++ } ++ ++ return 1; ++} ++#endif ++ ++#ifndef OPENSSL_NO_EC ++ ++EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) ++{ ++ if (pkey->type != EVP_PKEY_EC) ++ { ++ return NULL; ++ } ++ return pkey->pkey.ec; ++} ++ ++#endif ++ ++#ifndef OPENSSL_NO_DH ++DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey) ++{ ++ if (pkey->type != EVP_PKEY_DH) ++ { ++ return NULL; ++ } ++ return pkey->pkey.dh; ++} ++ ++int DH_bits(const DH *dh) ++{ ++ return BN_num_bits(dh->p); ++} ++ ++void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) ++{ ++ if (pub_key != NULL) ++ *pub_key = dh->pub_key; ++ if (priv_key != NULL) ++ *priv_key = dh->priv_key; ++} ++ ++int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) ++{ ++ /* If the field pub_key in dh is NULL, the corresponding input ++ * parameters MUST be non-NULL. The priv_key field may ++ * be left NULL. ++ */ ++ if (dh->pub_key == NULL && pub_key == NULL) ++ return 0; ++ ++ if (pub_key != NULL) ++ { ++ BN_free(dh->pub_key); ++ dh->pub_key = pub_key; ++ } ++ if (priv_key != NULL) ++ { ++ BN_free(dh->priv_key); ++ dh->priv_key = priv_key; ++ } ++ ++ return 1; ++} ++void DH_get0_pqg(const DH *dh, ++ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) ++{ ++ if (p != NULL) ++ *p = dh->p; ++ if (q != NULL) ++ *q = dh->q; ++ if (g != NULL) ++ *g = dh->g; ++} ++ ++int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) ++{ ++ /* If the fields p and g in d are NULL, the corresponding input ++ * parameters MUST be non-NULL. q may remain NULL. ++ */ ++ if ((dh->p == NULL && p == NULL) ++ || (dh->g == NULL && g == NULL)) ++ return 0; ++ ++ if (p != NULL) ++ { ++ BN_free(dh->p); ++ dh->p = p; ++ } ++ if (q != NULL) ++ { ++ BN_free(dh->q); ++ dh->q = q; ++ } ++ if (g != NULL) ++ { ++ BN_free(dh->g); ++ dh->g = g; ++ } ++ ++ if (q != NULL) ++ { ++ dh->length = BN_num_bits(q); ++ } ++ ++ return 1; ++} ++#endif ++ ++#ifndef OPENSSL_NO_RSA ++RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) ++{ ++ if (pkey->type != EVP_PKEY_RSA) ++ { ++ return NULL; ++ } ++ return pkey->pkey.rsa; ++} ++int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) ++{ ++ /* If the fields n and e in r are NULL, the corresponding input ++ * parameters MUST be non-NULL for n and e. d may be ++ * left NULL (in case only the public key is used). ++ */ ++ if ((r->n == NULL && n == NULL) ++ || (r->e == NULL && e == NULL)) ++ return 0; ++ ++ if (n != NULL) ++ { ++ BN_free(r->n); ++ r->n = n; ++ } ++ if (e != NULL) ++ { ++ BN_free(r->e); ++ r->e = e; ++ } ++ if (d != NULL) ++ { ++ BN_free(r->d); ++ r->d = d; ++ } ++ ++ return 1; ++} ++ ++int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) ++{ ++ /* If the fields p and q in r are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((r->p == NULL && p == NULL) ++ || (r->q == NULL && q == NULL)) ++ return 0; ++ ++ if (p != NULL) ++ { ++ BN_free(r->p); ++ r->p = p; ++ } ++ if (q != NULL) ++ { ++ BN_free(r->q); ++ r->q = q; ++ } ++ ++ return 1; ++} ++ ++int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) ++{ ++ /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input ++ * parameters MUST be non-NULL. ++ */ ++ if ((r->dmp1 == NULL && dmp1 == NULL) ++ || (r->dmq1 == NULL && dmq1 == NULL) ++ || (r->iqmp == NULL && iqmp == NULL)) ++ return 0; ++ ++ if (dmp1 != NULL) ++ { ++ BN_free(r->dmp1); ++ r->dmp1 = dmp1; ++ } ++ if (dmq1 != NULL) ++ { ++ BN_free(r->dmq1); ++ r->dmq1 = dmq1; ++ } ++ if (iqmp != NULL) ++ { ++ BN_free(r->iqmp); ++ r->iqmp = iqmp; ++ } ++ ++ return 1; ++} ++#endif ++ ++EVP_MD_CTX *EVP_MD_CTX_new(void) ++{ ++ return OPENSSL_malloc(sizeof(EVP_MD_CTX)); ++} ++int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) ++{ ++ return EVP_MD_CTX_cleanup(ctx); ++} ++void EVP_MD_CTX_free(EVP_MD_CTX *ctx) ++{ ++ EVP_MD_CTX_cleanup(ctx); ++ OPENSSL_free(ctx); ++} ++ ++void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, ++ const X509_ALGOR **palg) ++{ ++ if (psig != NULL) ++ *psig = req->signature; ++ if (palg != NULL) ++ *palg = req->sig_alg; ++} ++ ++X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req) ++{ ++ return req->req_info->pubkey; ++} ++ ++const ASN1_INTEGER *X509_get0_serialNumber(const X509 *a) ++{ ++ return a->cert_info->serialNumber; ++} ++ ++const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) ++{ ++ return x->cert_info->extensions; ++} ++int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) ++{ ++ req->req_info->enc.modified = 1; ++ return i2d_X509_REQ_INFO(req->req_info, pp); ++} ++const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x) ++{ ++ return x->revocationDate; ++} ++ ++const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x) ++{ ++ return x->serialNumber; ++} ++ ++const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const X509_REVOKED *r) ++{ ++ return r->extensions; ++} ++const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl) ++{ ++ return crl->crl->extensions; ++} ++ ++void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, ++ const X509_ALGOR **palg) ++{ ++ if (psig != NULL) ++ *psig = crl->signature; ++ if (palg != NULL) ++ *palg = crl->sig_alg; ++} ++ ++const ASN1_INTEGER *TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *a) ++{ ++ return a->status; ++} ++const STACK_OF(ASN1_UTF8STRING) *TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *a) ++{ ++ return a->text; ++} ++ ++const ASN1_BIT_STRING *TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *a) ++{ ++ return a->failure_info; ++} ++ ++#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER) ++int i2d_re_X509_tbs(X509 *x, unsigned char **pp) ++{ ++ x->cert_info->enc.modified = 1; ++ return i2d_X509_CINF(x->cert_info, pp); ++} ++ ++#if !defined(LIBRESSL_VERSION_NUMBER) ++void X509_get0_signature(CONSTIFY_X509_get0 ASN1_BIT_STRING **psig, ++ CONSTIFY_X509_get0 X509_ALGOR **palg, ++ const X509 *x) ++{ ++ if (psig) ++ *psig = x->signature; ++ if (palg) ++ *palg = x->sig_alg; ++} ++#endif ++ ++int X509_get_signature_nid(const X509 *x) ++{ ++ return OBJ_obj2nid(x->sig_alg->algorithm); ++} ++ ++#endif /* < 1.0.2 */ ++ ++ ++int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int f) ++{ ++ ctx->flags |= f; ++ return ctx->flags; ++} ++ ++int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int f) ++{ ++ ctx->flags = f; ++ return ctx->flags; ++} ++ ++BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *b) ++{ ++ ctx->data = b; ++ return ctx->data; ++} ++ ++X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s) ++{ ++ ctx->store = s; ++ return ctx->store; ++} ++ ++STACK_OF(X509) *TS_VERIFY_CTS_set_certs(TS_VERIFY_CTX *ctx, ++ STACK_OF(X509) *certs) ++{ ++ ctx->certs = certs; ++ return ctx->certs; ++} ++ ++unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx, ++ unsigned char *hexstr, long len) ++{ ++ ctx->imprint = hexstr; ++ ctx->imprint_len = len; ++ return ctx->imprint; ++} + +-#include "lua-compat/c-api/compat-5.3.c" ++#endif /* < 1.1.0 */ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/config.ld luvi-src-v2.7.6/deps/lua-openssl/src/config.ld +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/config.ld 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/config.ld 2019-02-13 11:53:24.275126573 +0100 +@@ -0,0 +1,9 @@ ++project='lua-openssl' ++title='lua-openssl Docmentation' ++description='Openssl binding for Lua' ++format='discount' ++backtick_references=false ++dir='doc' ++readme='README.md' ++style='!pale' ++kind_names={topic='Manual',script='Programs'} +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/crl.c luvi-src-v2.7.6/deps/lua-openssl/src/crl.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/crl.c 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/crl.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,9 +1,10 @@ +-/*=========================================================================*\ +-* crl.c +-* X509 certificate revoke routines for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++x509.crl module for lua-openssl binding, provide x509_crl as lua object. ++create and manage x509 certificate sign request ++@module x509.crl ++@usage ++ crl = require'openssl'.x509.crl ++*/ + #include "openssl.h" + #include "private.h" + #define CRYPTO_LOCK_REF +@@ -13,18 +14,33 @@ + int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); + int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); + ++#ifndef CRL_REASON_NONE ++#define CRL_REASON_NONE -1; ++#define CRL_REASON_UNSPECIFIED 0 ++#define CRL_REASON_KEY_COMPROMISE 1 ++#define CRL_REASON_CA_COMPROMISE 2 ++#define CRL_REASON_AFFILIATION_CHANGED 3 ++#define CRL_REASON_SUPERSEDED 4 ++#define CRL_REASON_CESSATION_OF_OPERATION 5 ++#define CRL_REASON_CERTIFICATE_HOLD 6 ++#define CRL_REASON_REMOVE_FROM_CRL 8 ++#define CRL_REASON_PRIVILEGE_WITHDRAWN 9 ++#define CRL_REASON_AA_COMPROMISE 10 ++#endif ++ + static const BIT_STRING_BITNAME reason_flags[] = + { +- {0, "Unused", "unused"}, +- {1, "Key Compromise", "keyCompromise"}, +- {2, "CA Compromise", "CACompromise"}, +- {3, "Affiliation Changed", "affiliationChanged"}, +- {4, "Superseded", "superseded"}, +- {5, "Cessation Of Operation", "cessationOfOperation"}, +- {6, "Certificate Hold", "certificateHold"}, +- {7, "Privilege Withdrawn", "privilegeWithdrawn"}, +- {8, "AA Compromise", "AACompromise"}, +- { -1, NULL, NULL} ++ { CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, ++ { CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise" }, ++ { CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise" }, ++ { CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged" }, ++ { CRL_REASON_SUPERSEDED, "Superseded", "superseded" }, ++ { CRL_REASON_CESSATION_OF_OPERATION, "Cessation Of Operation", "cessationOfOperation" }, ++ { CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold" }, ++ { CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL" }, ++ { CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn" }, ++ { CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise" }, ++ { -1, NULL, NULL } + }; + + static const int reason_num = sizeof(reason_flags) / sizeof(BIT_STRING_BITNAME) - 1; +@@ -76,6 +92,16 @@ static int reason_get(lua_State*L, int r + return reason; + } + ++static int openssl_x509_revoked_get_reason(X509_REVOKED *revoked) ++{ ++ int crit = 0; ++ int reason; ++ ASN1_ENUMERATED *areason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL); ++ reason = (crit == -1) ? CRL_REASON_NONE : ASN1_ENUMERATED_get(areason); ++ ASN1_ENUMERATED_free(areason); ++ return reason; ++} ++ + static X509_REVOKED *create_revoked(const BIGNUM* bn, time_t t, int reason) + { + X509_REVOKED *revoked = X509_REVOKED_new(); +@@ -86,9 +112,7 @@ static X509_REVOKED *create_revoked(cons + + X509_REVOKED_set_revocationDate(revoked, tm); + X509_REVOKED_set_serialNumber(revoked, it); +-#if OPENSSL_VERSION_NUMBER > 0x10000000L +- revoked->reason = reason; +-#else ++ + { + ASN1_ENUMERATED * e = ASN1_ENUMERATED_new(); + X509_EXTENSION * ext = X509_EXTENSION_new(); +@@ -102,57 +126,44 @@ static X509_REVOKED *create_revoked(cons + X509_EXTENSION_free(ext); + ASN1_ENUMERATED_free(e); + } +-#endif ++ + ASN1_TIME_free(tm); + ASN1_INTEGER_free(it); + + return revoked; + } + +-static LUA_FUNCTION(openssl_crl_add_revocked) ++static int openssl_revoked2table(lua_State*L, X509_REVOKED *revoked) + { +- X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +- BIGNUM* sn = BN_get(L, 2); +- time_t t = lua_tointeger(L, 3); +- int reason = reason_get(L, 4); ++ int reason = openssl_x509_revoked_get_reason(revoked); ++ lua_newtable(L); ++ AUXILIAR_SET(L, -1, "code", reason, number); ++ AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(reason), string); + +- int ret = 0; +- X509_REVOKED* revoked = create_revoked(sn, t, reason); +- ret = X509_CRL_add0_revoked(crl, revoked); +- lua_pushboolean(L, ret); +- BN_free(sn); +- return 1; +-} ++ PUSH_ASN1_INTEGER(L, X509_REVOKED_get0_serialNumber(revoked)); ++ lua_setfield(L, -2, "serialNumber"); + +-static int openssl_crl_extensions(lua_State* L) +-{ +- X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +- if (lua_isnone(L, 2)) +- { +- STACK_OF(X509_EXTENSION) *exts = crl->crl->extensions; +- if (exts) +- { +- openssl_sk_x509_extension_totable(L, exts); +- } +- else +- lua_pushnil(L); +- return 1; +- } +- else +- { +- STACK_OF(X509_EXTENSION) *exts = openssl_sk_x509_extension_fromtable(L, 2); +- int i, n; +- n = sk_X509_EXTENSION_num(exts); +- for (i = 0; i < n; i++) +- { +- X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); +- X509_CRL_add_ext(crl, X509_EXTENSION_dup(ext), i); +- }; +- sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); +- return openssl_pushresult(L, 1); +- } ++ PUSH_ASN1_TIME(L, X509_REVOKED_get0_revocationDate(revoked)); ++ lua_setfield(L, -2, "revocationDate"); ++ ++ lua_pushstring(L, "extensions"); ++ openssl_sk_x509_extension_totable(L, X509_REVOKED_get0_extensions(revoked)); ++ lua_rawset(L, -3); ++ return 1; + } + ++/*** ++create or generate a new x509_crl object. ++Note if not give evp_pkey, will create a new x509_crl object,if give will generate a signed x509_crl object. ++@function new ++@tparam[opt] table revoked_list ++@tparam[opt] x509 cacert ca cert to sign x509_crl ++@tparam[opt] evp_pkey capkey private key to sign x509_crl ++@tparam[opt] string|evp_md md_alg ++@tparam[opt=7*24*3600] number period to generate new crl ++@treturn x509_crl object ++@see x509_crl ++*/ + static LUA_FUNCTION(openssl_crl_new) + { + int i; +@@ -208,7 +219,7 @@ static LUA_FUNCTION(openssl_crl_new) + luaL_argcheck(L, X509_check_private_key(cacert, capkey) == 1, 3, "evp_pkey not match with x509 in #2"); + } + } +- md = lua_isnoneornil(L, 4) ? EVP_get_digestbyname("sha1") : get_digest(L, 4); ++ md = get_digest(L, 4, "sha256");; + step = lua_isnoneornil(L, 5) ? 7 * 24 * 3600 : luaL_checkint(L, 5); + + if (ret == 1) +@@ -247,6 +258,14 @@ static LUA_FUNCTION(openssl_crl_new) + return 1; + } + ++/*** ++read x509_crl from string or bio input ++@function read ++@tparam bio|string input input data ++@tparam[opt='auto'] string format support 'auto','pem','der' ++@treturn x509_crl certificate sign request object ++@see x509_crl ++*/ + static LUA_FUNCTION(openssl_crl_read) + { + BIO * in = load_bio_object(L, 1); +@@ -261,12 +280,12 @@ static LUA_FUNCTION(openssl_crl_read) + if (fmt == FORMAT_PEM) + { + crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); +- BIO_reset(in); ++ (void)BIO_reset(in); + } + else if (fmt == FORMAT_DER) + { + crl = d2i_X509_CRL_bio(in, NULL); +- BIO_reset(in); ++ (void)BIO_reset(in); + } + BIO_free(in); + if (crl) +@@ -277,6 +296,44 @@ static LUA_FUNCTION(openssl_crl_read) + return openssl_pushresult(L, 0); + } + ++/*** ++list all support reason info ++@function reason ++@treturn table contain support reason node like {lname=...,sname=...,bitnum=...} ++*/ ++static int openssl_crl_reason(lua_State *L) ++{ ++ int i; ++ const BIT_STRING_BITNAME* bitname; ++ lua_newtable(L); ++ for (i = 0, bitname = &reason_flags[i]; bitname->bitnum != -1; i++, bitname = &reason_flags[i]) ++ { ++ openssl_push_bit_string_bitname(L, bitname); ++ lua_rawseti(L, -2, i + 1); ++ } ++ return 1; ++} ++ ++static luaL_Reg R[] = ++{ ++ {"new", openssl_crl_new }, ++ {"read", openssl_crl_read}, ++ {"reason", openssl_crl_reason}, ++ ++ {NULL, NULL} ++}; ++ ++/*** ++openssl.x509_crl object ++@type x509_crl ++*/ ++ ++/*** ++set version key ++@function version ++@tparam integer version ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_crl_version) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +@@ -293,6 +350,80 @@ static LUA_FUNCTION(openssl_crl_version) + } + } + ++/*** ++add revoked entry to x509_crl object ++@function add ++@tparam string|number|bn serial ++@tparam number revokedtime ++@tparam[opt=0] number|string reason ++@treturn boolean result true for add success ++*/ ++static LUA_FUNCTION(openssl_crl_add_revocked) ++{ ++ X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); ++ BIGNUM* sn = BN_get(L, 2); ++ time_t t = lua_tointeger(L, 3); ++ int reason = reason_get(L, 4); ++ ++ int ret = 0; ++ X509_REVOKED* revoked = create_revoked(sn, t, reason); ++ ret = X509_CRL_add0_revoked(crl, revoked); ++ lua_pushboolean(L, ret); ++ BN_free(sn); ++ return 1; ++} ++ ++/*** ++get extensions of x509_crl ++@function extensions ++@treturn stack_of_x509_extension extensions ++*/ ++/*** ++set extensions to x509_crl object ++@function extensions ++@tparam stack_of_x509_extension extensions add to x509_crl ++@treturn boolean result ++*/ ++static int openssl_crl_extensions(lua_State* L) ++{ ++ X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); ++ if (lua_isnone(L, 2)) ++ { ++ const STACK_OF(X509_EXTENSION) *exts = X509_CRL_get0_extensions(crl); ++ if (exts) ++ { ++ openssl_sk_x509_extension_totable(L, exts); ++ } ++ else ++ lua_pushnil(L); ++ return 1; ++ } ++ else ++ { ++ STACK_OF(X509_EXTENSION) *exts = (STACK_OF(X509_EXTENSION) *)openssl_sk_x509_extension_fromtable(L, 2); ++ int i, n; ++ n = sk_X509_EXTENSION_num(exts); ++ for (i = 0; i < n; i++) ++ { ++ X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); ++ X509_CRL_add_ext(crl, X509_EXTENSION_dup(ext), i); ++ }; ++ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); ++ return openssl_pushresult(L, 1); ++ } ++} ++ ++/*** ++get issuer x509_name object ++@function issuer ++@treturn x509_name ++*/ ++/*** ++set issuer x509_name object ++@function issuer ++@tparam x509_name|x509 issuer ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_crl_issuer) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +@@ -300,13 +431,13 @@ static LUA_FUNCTION(openssl_crl_issuer) + { + return openssl_push_xname_asobject(L, X509_CRL_get_issuer(crl)); + } +- else if (auxiliar_isclass(L, "openssl.x509_name", 2)) ++ else if (auxiliar_getclassudata(L, "openssl.x509_name", 2)) + { + X509_NAME* xn = CHECK_OBJECT(2, X509_NAME, "openssl.x509_name"); + int ret = X509_CRL_set_issuer_name(crl, xn); + return openssl_pushresult(L, ret); + } +- else if (auxiliar_isclass(L, "openssl.x509", 2)) ++ else if (auxiliar_getclassudata(L, "openssl.x509", 2)) + { + X509* x = CHECK_OBJECT(2, X509, "openssl.x509"); + int ret = X509_CRL_set_issuer_name(crl, X509_get_issuer_name(x)); +@@ -319,6 +450,17 @@ static LUA_FUNCTION(openssl_crl_issuer) + return 0; + } + ++/*** ++get lastUpdate time ++@function lastUpdate ++@treturn string lastUpdate ++*/ ++/*** ++set lastUpdate time ++@function lastUpdate ++@tparam number lastUpdate ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_crl_lastUpdate) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +@@ -341,6 +483,17 @@ static LUA_FUNCTION(openssl_crl_lastUpda + } + } + ++/*** ++get nextUpdate time ++@function nextUpdate ++@treturn string nextUpdate ++*/ ++/*** ++set nextUpdate time ++@function nextUpdate ++@tparam number nextUpdate ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_crl_nextUpdate) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +@@ -363,6 +516,18 @@ static LUA_FUNCTION(openssl_crl_nextUpda + } + } + ++/*** ++get updateTime time ++@function updateTime ++@treturn string lastUpdate ++*/ ++/*** ++set updateTime time ++@function updateTime ++@tparam[opt=os.time()] lastUpdate, default use current time ++@tparam number periord periord how long time(seconds) ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_crl_updateTime) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +@@ -408,6 +573,11 @@ static LUA_FUNCTION(openssl_crl_updateTi + } + } + ++/*** ++sore crl entry in x509_crl object ++@function sort ++@treturn boolean result true for success and others for fail ++*/ + static LUA_FUNCTION(openssl_crl_sort) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +@@ -415,33 +585,61 @@ static LUA_FUNCTION(openssl_crl_sort) + return openssl_pushresult(L, ret); + } + ++/*** ++verify x509_crl object signature ++@function verify ++@tparam x509|evp_pkey key ca cert or public to verify signature ++@treturn boolean result true for success and others for fail ++*/ + static LUA_FUNCTION(openssl_crl_verify) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +- X509* cacert = CHECK_OBJECT(2, X509, "openssl.x509"); ++ EVP_PKEY *pub = NULL; ++ int ret; ++ luaL_argcheck(L, ++ auxiliar_getclassudata(L, "openssl.x509", 2) || ++ auxiliar_getclassudata(L, "openssl.evp_pkey", 2), ++ 2, ++ "must be x509 or evp_pkey object"); ++ if (auxiliar_getclassudata(L, "openssl.evp_pkey", 2)) ++ { ++ pub = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); ++ ret = X509_CRL_verify(crl, pub); ++ } ++ else ++ { ++ X509* cacert = CHECK_OBJECT(2, X509, "openssl.x509"); ++ pub = X509_get_pubkey(cacert); ++ ret = X509_CRL_verify(crl, pub); ++ EVP_PKEY_free(pub); ++ } + +- int ret = X509_CRL_verify(crl, cacert->cert_info->key->pkey); + return openssl_pushresult(L, ret); + } + ++/*** ++sign x509_crl ++@function sign ++@tparam evp_pkey pkey private key to sign x509 ++@tparam x509|x509_name cacert or cacert x509_name ++@tparam[opt='sha1WithRSAEncryption'] string|md_digest md_alg ++@treturn boolean result true for check pass ++*/ + LUA_FUNCTION(openssl_crl_sign) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); + EVP_PKEY *key = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); +- const EVP_MD *md = lua_isnoneornil(L, 4) +- ? EVP_get_digestbyname("sha1") : get_digest(L, 4); +- ++ const EVP_MD *md = get_digest(L, 4, "sha256"); + int ret = 1; + +- luaL_argcheck(L, openssl_pkey_is_private(key), 2, "must be private key"); +- luaL_argcheck(L, auxiliar_isclass(L, "openssl.x509", 3) || auxiliar_isclass(L, "openssl.x509_name", 3), ++ luaL_argcheck(L, auxiliar_getclassudata(L, "openssl.x509", 3) || auxiliar_getclassudata(L, "openssl.x509_name", 3), + 3, "must be openssl.x509 or openssl.x509_name object"); +- if (auxiliar_isclass(L, "openssl.x509_name", 3)) ++ if (auxiliar_getclassudata(L, "openssl.x509_name", 3)) + { + X509_NAME* xn = CHECK_OBJECT(3, X509_NAME, "openssl.x509_name"); + ret = X509_CRL_set_issuer_name(crl, xn); + } +- else if (auxiliar_isclass(L, "openssl.x509", 3)) ++ else if (auxiliar_getclassudata(L, "openssl.x509", 3)) + { + X509* ca = CHECK_OBJECT(3, X509, "openssl.x509"); + ret = X509_CRL_set_issuer_name(crl, X509_get_issuer_name(ca)); +@@ -461,13 +659,18 @@ LUA_FUNCTION(openssl_crl_sign) + return openssl_pushresult(L, ret); + } + ++/*** ++get digest of x509_crl ++@function digest ++@tparam[opt='SHA1'] evp_md|string md_alg default use sha1 ++@treturn string digest result ++*/ + static LUA_FUNCTION(openssl_crl_digest) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); + byte buf[EVP_MAX_MD_SIZE]; + unsigned int lbuf = sizeof(buf); +- const EVP_MD *md = lua_isnoneornil(L, 2) +- ? EVP_get_digestbyname("sha1") : get_digest(L, 2); ++ const EVP_MD *md = get_digest(L, 2, "sha256"); + + int ret = X509_CRL_digest(crl, md, buf, &lbuf); + if (ret == 1) +@@ -478,6 +681,14 @@ static LUA_FUNCTION(openssl_crl_digest) + return openssl_pushresult(L, ret); + } + ++/*** ++compare with other x509_crl object ++@function cmp ++@tparam x509_crl other ++@treturn boolean result true for equals or false ++@usage ++ x:cmp(y) == (x==y) ++*/ + static LUA_FUNCTION(openssl_crl_cmp) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +@@ -488,17 +699,24 @@ static LUA_FUNCTION(openssl_crl_cmp) + } + + #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined (LIBRESSL_VERSION_NUMBER) ++/*** ++make a delta x509_crl object ++@function diff ++@tparam x509_crl newer ++@tparam evp_pkey pkey ++@tparam[opt='sha1'] evp_md|string md_alg ++@tparam[opt=0] integer flags ++@treturn x509_crl delta result x509_crl object ++*/ + static LUA_FUNCTION(openssl_crl_diff) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); + X509_CRL *newer = CHECK_OBJECT(2, X509_CRL, "openssl.x509_crl"); + EVP_PKEY* pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); +- const EVP_MD *md = lua_isnoneornil(L, 4) +- ? EVP_get_digestbyname("sha1") : get_digest(L, 4); ++ const EVP_MD *md = get_digest(L, 4, "sha256"); + unsigned int flags = luaL_optinteger(L, 5, 0); + X509_CRL *diff; + +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 3, "must be private key"); + diff = X509_CRL_diff(crl, newer, pkey, md, flags); + if (diff) + { +@@ -508,22 +726,35 @@ static LUA_FUNCTION(openssl_crl_diff) + lua_pushnil(L); + return 1; + } ++ ++/*** ++check x509_crl with evp_pkey ++@function check ++@tparam evp_pkey pkey ++@tparam[opt=0] integer flags ++@treturn boolean result true for pass ++*/ + static LUA_FUNCTION(openssl_crl_check) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); + EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); + unsigned long flags = luaL_optinteger(L, 3, X509_V_FLAG_SUITEB_128_LOS); +- int ret; +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 2, "must be private key"); +- ret = X509_CRL_check_suiteb(crl, pkey, flags); ++ int ret = X509_CRL_check_suiteb(crl, pkey, flags); + return openssl_pushresult(L, ret == X509_V_OK); + } + #endif + ++/*** ++parse x509_crl object as table ++@function parse ++@tparam[opt=true] shortname default will use short object name ++@treturn table result ++*/ + static LUA_FUNCTION(openssl_crl_parse) + { + X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); + int num, i; ++ const X509_ALGOR *alg; + + lua_newtable(L); + AUXILIAR_SET(L, -1, "version", X509_CRL_get_version(crl), integer); +@@ -536,7 +767,7 @@ static LUA_FUNCTION(openssl_crl_parse) + } + + { +- const EVP_MD *digest = EVP_get_digestbyname("sha1"); ++ const EVP_MD *digest = EVP_get_digestbyname("sha256"); + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int l = sizeof(md); + +@@ -558,58 +789,50 @@ static LUA_FUNCTION(openssl_crl_parse) + PUSH_ASN1_TIME(L, X509_CRL_get_nextUpdate(crl)); + lua_setfield(L, -2, "nextUpdate"); + +- openssl_push_x509_algor(L, crl->crl->sig_alg); +- lua_setfield(L, -2, "sig_alg"); +- +-#if OPENSSL_VERSION_NUMBER > 0x00909000L +- if (crl->crl_number) + { +- PUSH_ASN1_INTEGER(L, crl->crl_number); +- lua_setfield(L, -2, "crl_number"); ++ const ASN1_BIT_STRING *sig = NULL; ++ const X509_ALGOR *sig_alg = NULL; ++ ++ X509_CRL_get0_signature(crl, &sig, &alg); ++ PUSH_OBJECT(sig_alg, "openssl.x509_algor"); ++ lua_setfield(L, -2, "sig_alg"); ++ PUSH_ASN1_STRING(L, sig); ++ lua_setfield(L, -2, "signature"); + } +-#endif +- if (crl->crl->extensions) + { +- lua_pushstring(L, "extensions"); +- openssl_sk_x509_extension_totable(L, crl->crl->extensions); +- lua_rawset(L, -3); ++ ASN1_INTEGER *crl_number = X509_CRL_get_ext_d2i(crl, NID_crl_number, NULL, NULL); ++ if (crl_number) ++ { ++ PUSH_ASN1_INTEGER(L, crl_number); ++ lua_setfield(L, -2, "crl_number"); ++ } + } +- +- num = sk_X509_REVOKED_num(crl->crl->revoked); +- lua_newtable(L); +- for (i = 0; i < num; i++) + { +- X509_REVOKED *revoked = sk_X509_REVOKED_value(crl->crl->revoked, i); +- lua_newtable(L); +- +-#if OPENSSL_VERSION_NUMBER > 0x10000000L +- AUXILIAR_SET(L, -1, "CRLReason", openssl_i2s_revoke_reason(revoked->reason), string); +-#else ++ const STACK_OF(X509_EXTENSION) *extensions = X509_CRL_get0_extensions(crl); ++ if (extensions) + { +- int crit = 0; +- void* reason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL); +- +- AUXILIAR_SET(L, -1, "CRLReason", openssl_i2s_revoke_reason(ASN1_ENUMERATED_get(reason)), string); +- ASN1_ENUMERATED_free(reason); ++ openssl_sk_x509_extension_totable(L, extensions); ++ lua_setfield(L, -2, "extensions"); + } +-#endif +- PUSH_ASN1_INTEGER(L, revoked->serialNumber); +- lua_setfield(L, -2, "serialNumber"); +- +- PUSH_ASN1_TIME(L, revoked->revocationDate); +- lua_setfield(L, -2, "revocationDate"); ++ } + +- if (crl->crl->extensions) ++ { ++ STACK_OF(X509_REVOKED) *revokeds = X509_CRL_get_REVOKED(crl); ++ if (revokeds) + { +- lua_pushstring(L, "extensions"); +- openssl_sk_x509_extension_totable(L, crl->crl->extensions); +- lua_rawset(L, -3); +- } ++ num = sk_X509_REVOKED_num(revokeds); ++ lua_newtable(L); ++ for (i = 0; i < num; i++) ++ { ++ X509_REVOKED *revoked = sk_X509_REVOKED_value(revokeds, i); ++ openssl_revoked2table(L, revoked); ++ lua_rawseti(L, -2, i + 1); ++ } + +- lua_rawseti(L, -2, i + 1); ++ lua_setfield(L, -2, "revoked"); ++ } + } + +- lua_setfield(L, -2, "revoked"); + return 1; + } + +@@ -620,6 +843,13 @@ static LUA_FUNCTION(openssl_crl_free) + return 0; + } + ++/*** ++export x509_crl to string ++@function export ++@tparam[opt='pem'] string format ++@tparam[opt='true'] boolean noext not export extension ++@treturn string ++*/ + static LUA_FUNCTION(openssl_crl_export) + { + X509_CRL * crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +@@ -663,49 +893,57 @@ static LUA_FUNCTION(openssl_crl_export) + return 1; + } + +- ++/*** ++get count of revoked entry ++@function count ++@treturn number count ++@usage ++ assert(#crl==crl:count()) ++*/ + static LUA_FUNCTION(openssl_crl_count) + { + X509_CRL * crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +- int n = sk_X509_REVOKED_num(crl->crl->revoked); ++ STACK_OF(X509_REVOKED) *revokeds = X509_CRL_get_REVOKED(crl); ++ int n = revokeds ? sk_X509_REVOKED_num(revokeds) : 0; + lua_pushinteger(L, n); + return 1; + } + ++/*** ++get revoekd entry ++@function get ++@tparam number index ++@treturn table revoekd ++*/ + static LUA_FUNCTION(openssl_crl_get) + { + X509_CRL * crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); +- int i = luaL_checkint(L, 2); +- if (i >= 0 && i < sk_X509_REVOKED_num(crl->crl->revoked)) ++ STACK_OF(X509_REVOKED) *revokeds = X509_CRL_get_REVOKED(crl); ++ X509_REVOKED *revoked = NULL; ++ int i = 0; ++ if (lua_isinteger(L, 2)) ++ { ++ i = lua_tointeger(L, 2); ++ luaL_argcheck(L, (i >= 0 && i < sk_X509_REVOKED_num(revokeds)), 2, "Out of range"); ++ revoked = sk_X509_REVOKED_value(revokeds, i); ++ } ++ else + { +- X509_REVOKED *revoked = sk_X509_REVOKED_value(crl->crl->revoked, i); +- +- lua_newtable(L); +- +-#if OPENSSL_VERSION_NUMBER > 0x10000000L +- AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(revoked->reason), string); +-#else +- { +- int crit = 0; +- void* reason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL); +- +- AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(ASN1_ENUMERATED_get(reason)), string); +- ASN1_ENUMERATED_free(reason); +- } +-#endif +- PUSH_ASN1_INTEGER(L, revoked->serialNumber); +- lua_setfield(L, -2, "serialNumber"); +- +- PUSH_ASN1_TIME(L, revoked->revocationDate); +- lua_setfield(L, -2, "revocationDate"); +- +- if (crl->crl->extensions) ++ ASN1_STRING *sn = CHECK_OBJECT(2, ASN1_STRING, "openssl.asn1_integer"); ++ int cnt = sk_X509_REVOKED_num(revokeds); ++ for (i = 0; i < cnt; i++) + { +- lua_pushstring(L, "extensions"); +- openssl_sk_x509_extension_totable(L, crl->crl->extensions); +- lua_rawset(L, -3); ++ X509_REVOKED *rev = sk_X509_REVOKED_value(revokeds, i); ++ if (ASN1_STRING_cmp(X509_REVOKED_get0_serialNumber(rev), sn) == 0) ++ { ++ revoked = rev; ++ break; ++ } + } +- return 1; ++ } ++ if (revoked) ++ { ++ openssl_revoked2table(L, revoked); + } + else + lua_pushnil(L); +@@ -752,55 +990,38 @@ static luaL_Reg crl_funcs[] = + static int openssl_revoked_info(lua_State* L) + { + X509_REVOKED* revoked = CHECK_OBJECT(1, X509_REVOKED, "openssl.x509_revoked"); +- lua_newtable(L); +- +-#if OPENSSL_VERSION_NUMBER > 0x10000000L +- AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(revoked->reason), string); +-#else +- { +- int crit = 0; +- void* reason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL); +- +- AUXILIAR_SET(L, -1, "reason", openssl_i2s_revoke_reason(ASN1_ENUMERATED_get(reason)), string); +- ASN1_ENUMERATED_free(reason); +- } +-#endif +- PUSH_ASN1_INTEGER(L, revoked->serialNumber); +- lua_setfield(L, -2, "serialNumber"); +- +- PUSH_ASN1_TIME(L, revoked->revocationDate); +- lua_setfield(L, -2, "revocationDate"); +- +- if (revoked->extensions) +- { +- lua_pushstring(L, "extensions"); +- openssl_sk_x509_extension_totable(L, revoked->extensions); +- lua_rawset(L, -3); +- } +- return 1; ++ return openssl_revoked2table(L, revoked); + }; + + static int openssl_revoked_reason(lua_State* L) + { + X509_REVOKED* revoked = CHECK_OBJECT(1, X509_REVOKED, "openssl.x509_revoked"); +-#if OPENSSL_VERSION_NUMBER > 0x00909000L +- lua_pushstring(L, openssl_i2s_revoke_reason(revoked->reason)); +- lua_pushinteger(L, revoked->reason); +- return 2; +-#else +- /* ++ if (lua_isnone(L, 2)) + { +- int crit = 0; +- void* reason = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason, &crit, NULL); +- lua_pushstring(L, openssl_i2s_revoke_reason(ASN1_ENUMERATED_get(reason)).lname); +- lua_pushinteger(revoked->reason); +- ASN1_ENUMERATED_free(reason); +- }*/ ++ int reason = openssl_x509_revoked_get_reason(revoked); ++ lua_pushinteger(L, reason); ++ lua_pushstring(L, openssl_i2s_revoke_reason(reason)); ++ return 2; ++ } ++ else ++ { ++ int reason = reason_get(L, 2); ++ ASN1_ENUMERATED * e = ASN1_ENUMERATED_new(); ++ X509_EXTENSION * ext = X509_EXTENSION_new(); ++ ++ ASN1_ENUMERATED_set(e, reason); ++ ++ X509_EXTENSION_set_data(ext, e); ++ X509_EXTENSION_set_object(ext, OBJ_nid2obj(NID_crl_reason)); ++ X509_REVOKED_add_ext(revoked, ext, 0); ++ ++ X509_EXTENSION_free(ext); ++ ASN1_ENUMERATED_free(e); ++ } + return 0; +-#endif + } + +-static time_t ASN1_GetTimeT(ASN1_TIME* time) ++static time_t ASN1_GetTimeT(const ASN1_TIME* time) + { + struct tm t; + const char* str = (const char*) time->data; +@@ -841,27 +1062,29 @@ static time_t ASN1_GetTimeT(ASN1_TIME* t + static int openssl_revoked_revocationDate(lua_State* L) + { + X509_REVOKED* revoked = CHECK_OBJECT(1, X509_REVOKED, "openssl.x509_revoked"); +- PUSH_ASN1_TIME(L, revoked->revocationDate); +- lua_pushinteger(L, (LUA_INTEGER)ASN1_GetTimeT(revoked->revocationDate)); ++ const ASN1_TIME* time = X509_REVOKED_get0_revocationDate(revoked); ++ lua_pushinteger(L, (LUA_INTEGER)ASN1_GetTimeT(time)); ++ PUSH_ASN1_TIME(L, time); + return 2; + } + + static int openssl_revoked_serialNumber(lua_State* L) + { + X509_REVOKED* revoked = CHECK_OBJECT(1, X509_REVOKED, "openssl.x509_revoked"); +- BIGNUM *bn = ASN1_INTEGER_to_BN(revoked->serialNumber, NULL); +- PUSH_ASN1_INTEGER(L, revoked->serialNumber); ++ const ASN1_INTEGER *serialNumber = X509_REVOKED_get0_serialNumber(revoked); ++ BIGNUM *bn = ASN1_INTEGER_to_BN(serialNumber, NULL); + PUSH_OBJECT(bn, "openssl.bn"); ++ PUSH_ASN1_INTEGER(L, serialNumber); + return 2; + } + + static int openssl_revoked_extensions(lua_State* L) + { + X509_REVOKED* revoked = CHECK_OBJECT(1, X509_REVOKED, "openssl.x509_revoked"); +- +- if (revoked->extensions) ++ const STACK_OF(X509_EXTENSION) *exts = X509_REVOKED_get0_extensions(revoked); ++ if (exts) + { +- openssl_sk_x509_extension_totable(L, revoked->extensions); ++ openssl_sk_x509_extension_totable(L, exts); + } + else + lua_pushnil(L); +@@ -889,27 +1112,6 @@ static luaL_Reg revoked_funcs[] = + {NULL, NULL} + }; + +-static int openssl_crl_reason(lua_State *L) +-{ +- int i; +- const BIT_STRING_BITNAME* bitname; +- lua_newtable(L); +- for (i = 0, bitname = &reason_flags[i]; bitname->bitnum != -1; i++, bitname = &reason_flags[i]) +- { +- openssl_push_bit_string_bitname(L, bitname); +- lua_rawseti(L, -2, i + 1); +- } +- return 1; +-} +- +-static luaL_Reg R[] = +-{ +- {"new", openssl_crl_new }, +- {"read", openssl_crl_read}, +- {"reason", openssl_crl_reason}, +- {NULL, NULL} +-}; +- + IMP_LUA_SK(X509_CRL, x509_crl) + + int luaopen_x509_crl(lua_State *L) +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/csr.c luvi-src-v2.7.6/deps/lua-openssl/src/csr.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/csr.c 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/csr.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,12 +1,21 @@ +-/*=========================================================================*\ +-* csr.c +-* X509 certificate sign request routines for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++x509.req module for lua-openssl binding, provide x509_req as lua object. ++create and manage x509 certificate sign request ++@module x509.req ++@usage ++ req = require'openssl'.x509.req ++*/ ++ + #include "openssl.h" + #include "private.h" + ++/*** ++read x509_req from string or bio input ++@function read ++@tparam bio|string input input data ++@tparam[opt='auto'] string format support 'auto','pem','der' ++@treturn x509_req certificate sign request object ++*/ + static LUA_FUNCTION(openssl_csr_read) + { + BIO * in = load_bio_object(L, 1); +@@ -21,12 +30,12 @@ static LUA_FUNCTION(openssl_csr_read) + if (fmt == FORMAT_PEM) + { + csr = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); +- BIO_reset(in); ++ (void)BIO_reset(in); + } + else if (fmt == FORMAT_DER) + { + csr = d2i_X509_REQ_bio(in, NULL); +- BIO_reset(in); ++ (void)BIO_reset(in); + } + BIO_free(in); + +@@ -38,18 +47,95 @@ static LUA_FUNCTION(openssl_csr_read) + return openssl_pushresult(L, 0); + } + ++/*** ++create or generate a new x509_req object. ++Note if not give evp_pkey, will create a new x509_req object,or will generate a signed x509_req object. ++@function new ++@tparam[opt] x509_name subject subject name set to x509_req ++@tparam[opt] stack_of_x509_extension extensions add to x509_req ++@tparam[opt] stack_of_x509_attribute attributes add to x509_req ++@tparam[opt] evp_pkey pkey private key sign the x509_req, and set as public key ++@tparam[opt='sha1WithRSAEncryption'] evp_digest|string md_alg, only used when pkey exist, and should fellow pkey ++@treturn x509_req certificate sign request object ++@see x509_req ++*/ ++static LUA_FUNCTION(openssl_csr_new) ++{ ++ X509_REQ *csr = X509_REQ_new(); ++ int i; ++ int n = lua_gettop(L); ++ int ret = X509_REQ_set_version(csr, 0L); ++ ++ for (i = 1; ret == 1 && i <= n; i++) ++ { ++ luaL_argcheck(L, ++ auxiliar_getclassudata(L, "openssl.x509_name", i) || ++ auxiliar_getclassudata(L, "openssl.evp_pkey", i), ++ i, "must be x509_name or evp_pkey"); ++ if (auxiliar_getclassudata(L, "openssl.x509_name", i)) ++ { ++ X509_NAME * subject = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name"); ++ ret = X509_REQ_set_subject_name(csr, subject); ++ } ++ if (auxiliar_getclassudata(L, "openssl.evp_pkey", i)) ++ { ++ EVP_PKEY *pkey; ++ const EVP_MD *md; ++ luaL_argcheck(L, i == n || i == n - 1, i, "must is evp_pkey object"); ++ ++ pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey"); ++ ++ if (i == n - 1) ++ md = get_digest(L, n, NULL); ++ else ++ md = EVP_get_digestbyname("sha256"); ++ ++ ret = X509_REQ_set_pubkey(csr, pkey); ++ if (ret == 1) ++ { ++ ret = X509_REQ_sign(csr, pkey, md); ++ if (ret > 0) ++ ret = 1; ++ } ++ break; ++ } ++ }; + +-static X509 *X509_REQ_to_X509_a(X509_REQ *r, int days, EVP_PKEY *pkey) ++ if (ret == 1) ++ PUSH_OBJECT(csr, "openssl.x509_req"); ++ else ++ { ++ X509_REQ_free(csr); ++ return openssl_pushresult(L, ret); ++ } ++ return 1; ++} ++ ++static luaL_Reg R[] = ++{ ++ {"new", openssl_csr_new }, ++ {"read", openssl_csr_read }, ++ ++ {NULL, NULL} ++}; ++ ++/*** ++openssl.x509_req object ++@type x509_req ++*/ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++static X509 *X509_REQ_to_X509_ex(X509_REQ *r, int days, EVP_PKEY *pkey, const EVP_MD* md) + { + X509 *ret = NULL; + X509_CINF *xi = NULL; + X509_NAME *xn; +- EVP_PKEY* pubkey; ++ EVP_PKEY *pubkey = NULL; ++ int res; + + if ((ret = X509_new()) == NULL) + { + X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); +- goto err; ++ return NULL; + } + + /* duplicate the request */ +@@ -57,10 +143,12 @@ static X509 *X509_REQ_to_X509_a(X509_REQ + + if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) + { +- if ((xi->version = M_ASN1_INTEGER_new()) == NULL) goto err; +- if (!ASN1_INTEGER_set(xi->version, 2)) goto err; +- /* xi->extensions=ri->attributes; <- bad, should not ever be done +- ri->attributes=NULL; */ ++ if ((xi->version = M_ASN1_INTEGER_new()) == NULL) ++ goto err; ++ if (!ASN1_INTEGER_set(xi->version, 2)) ++ goto err; ++ /*- xi->extensions=ri->attributes; <- bad, should not ever be done ++ ri->attributes=NULL; */ + } + + xn = X509_REQ_get_subject_name(r); +@@ -71,12 +159,17 @@ static X509 *X509_REQ_to_X509_a(X509_REQ + + if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) + goto err; +- if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) == NULL) ++ if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) == ++ NULL) + goto err; ++ + pubkey = X509_REQ_get_pubkey(r); +- X509_set_pubkey(ret, pubkey); ++ res = X509_set_pubkey(ret, pubkey); + EVP_PKEY_free(pubkey); +- if (!X509_sign(ret, pkey, EVP_get_digestbyobj(r->sig_alg->algorithm))) ++ ++ if (!md) ++ goto err; ++ if (!res || !X509_sign(ret, pkey, md)) + goto err; + if (0) + { +@@ -86,16 +179,24 @@ err: + } + return (ret); + } ++#endif + ++/*** ++convert x509_req to x509 object ++@function to_x509 ++@treturn x509 object not signed ++*/ + static LUA_FUNCTION(openssl_csr_to_x509) + { + X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); + EVP_PKEY * pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); + int days = luaL_optint(L, 3, 365); +- X509* cert = X509_REQ_to_X509_a(csr, days, pkey); +- +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 2, "must be private key"); +- ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ const EVP_MD* md = get_digest(L, 4, "sha256"); ++ X509* cert = X509_REQ_to_X509_ex(csr, days, pkey, md); ++#else ++ X509* cert = X509_REQ_to_X509(csr, days, pkey); ++#endif + if (cert) + { + PUSH_OBJECT(cert, "openssl.x509"); +@@ -104,6 +205,13 @@ static LUA_FUNCTION(openssl_csr_to_x509) + return openssl_pushresult(L, 0); + } + ++/*** ++export x509_req to string ++@function export ++@tparam[opt='pem'] string format ++@tparam[opt='true'] boolean noext not export extension ++@treturn string ++*/ + static LUA_FUNCTION(openssl_csr_export) + { + X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +@@ -151,17 +259,19 @@ static LUA_FUNCTION(openssl_csr_export) + return 1; + } + ++/*** ++get digest of x509_req ++@function digest ++@tparam[opt='SHA1'] evp_md|string md_alg default use sha1 ++@treturn string digest result ++*/ + static LUA_FUNCTION(openssl_csr_digest) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +- const EVP_MD *md = NULL; + unsigned char buf[EVP_MAX_MD_SIZE]; + unsigned int len = sizeof(buf); + int ret; +- if (lua_isnoneornil(L, 2)) +- md = EVP_get_digestbyname("SHA1"); +- else +- md = get_digest(L, 2); ++ const EVP_MD *md = get_digest(L, 2, "sha256"); + + ret = X509_REQ_digest(csr, md, buf, &len); + if (ret == 1) +@@ -172,16 +282,25 @@ static LUA_FUNCTION(openssl_csr_digest) + return openssl_pushresult(L, ret); + }; + ++/*** ++check x509_req with evp_pkey ++@function check ++@tparam evp_pkey pkey ++@treturn boolean result true for check pass ++*/ + static LUA_FUNCTION(openssl_csr_check) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); + EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); +- int ret; +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 2, "must be private key"); +- ret = X509_REQ_check_private_key(csr, pkey); ++ int ret = X509_REQ_check_private_key(csr, pkey); + return openssl_pushresult(L, ret); + }; + ++/*** ++clone x509_req object ++@function dup ++@treturn x509_req object ++*/ + static LUA_FUNCTION(openssl_csr_dup) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +@@ -190,6 +309,11 @@ static LUA_FUNCTION(openssl_csr_dup) + return 1; + }; + ++/*** ++verify x509_req signature ++@function verify ++@treturn boolean result true for verify pass ++*/ + static LUA_FUNCTION(openssl_csr_verify) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +@@ -204,129 +328,115 @@ static LUA_FUNCTION(openssl_csr_verify) + return 1; + }; + +-static LUA_FUNCTION(openssl_csr_new) +-{ +- X509_REQ *csr = X509_REQ_new(); +- int i; +- int n = lua_gettop(L); +- int ret = X509_REQ_set_version(csr, 0L); +- +- for (i = 1; ret == 1 && i <= n; i++) +- { +- luaL_argcheck(L, +- auxiliar_isclass(L, "openssl.x509_name", i) || +- auxiliar_isclass(L, "openssl.evp_pkey", i), +- i, "must be x509_name"); +- if (auxiliar_isclass(L, "openssl.x509_name", i)) +- { +- X509_NAME * subject = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name"); +- ret = X509_REQ_set_subject_name(csr, subject); +- } +- if (auxiliar_isclass(L, "openssl.evp_pkey", i)) +- { +- EVP_PKEY *pkey; +- const EVP_MD *md; +- luaL_argcheck(L, i == n || i == n - 1, i, "must is evp_pkey object"); +- +- pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey"); +- +- luaL_argcheck(L, openssl_pkey_is_private(pkey), i, "must be private key"); +- +- if (i == n - 1) +- md = get_digest(L, n); +- else +- md = EVP_get_digestbyname("sha1"); +- +- ret = X509_REQ_set_pubkey(csr, pkey); +- if (ret == 1) +- { +- ret = X509_REQ_sign(csr, pkey, md); +- if (ret > 0) +- ret = 1; +- } +- break; +- } +- }; +- +- if (ret == 1) +- PUSH_OBJECT(csr, "openssl.x509_req"); +- else +- { +- X509_REQ_free(csr); +- return openssl_pushresult(L, ret); +- } +- return 1; +-} ++/*** ++sign x509_req object + ++@function sign ++@tparam evp_pkey pkey private key which to sign x509_req object ++@tparam number|string|evp_md md message digest alg used to sign ++@treturn boolean result true for suceess ++*/ + static LUA_FUNCTION(openssl_csr_sign) + { + X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +- EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); +- if (openssl_pkey_is_private(pkey)) ++ EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr); ++ if (auxiliar_getclassudata(L, "openssl.evp_pkey", 2)) + { +- const EVP_MD* md = lua_isnone(L, 3) ? EVP_get_digestbyname("sha1") : get_digest(L, 3); +- int ret = X509_REQ_set_pubkey(csr, pkey); +- if (ret == 1) ++ EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); ++ const EVP_MD* md = get_digest(L, 3, "sha256"); ++ int ret = 1; ++ if (pubkey == NULL) + { +- ret = X509_REQ_sign(csr, pkey, md); +- if (ret > 0) +- ret = 1; ++ BIO* bio = BIO_new(BIO_s_mem()); ++ if ((ret = i2d_PUBKEY_bio(bio, pkey)) == 1) ++ { ++ pubkey = d2i_PUBKEY_bio(bio, NULL); ++ if (pubkey) ++ { ++ ret = X509_REQ_set_pubkey(csr, pubkey); ++ EVP_PKEY_free(pubkey); ++ } ++ else ++ { ++ ret = 0; ++ } ++ } ++ BIO_free(bio); + } +- +- return openssl_pushresult(L, 1); +- } +- else if (lua_isnoneornil(L, 3) && X509_REQ_set_pubkey(csr, pkey)) +- { +- unsigned char* tosign = NULL; +- const ASN1_ITEM *it = ASN1_ITEM_rptr(X509_REQ_INFO); +- int inl = ASN1_item_i2d((void*)csr->req_info, &tosign, it); +- if (inl > 0 && tosign) ++ else + { +- lua_pushlstring(L, (const char*)tosign, inl); +- OPENSSL_free(tosign); +- return 1; ++ EVP_PKEY_free(pubkey); + } +- return openssl_pushresult(L, 0); ++ if (ret == 1) ++ ret = X509_REQ_sign(csr, pkey, md); ++ return openssl_pushresult(L, ret); + } +- else ++ else if (lua_isstring(L, 2)) + { + size_t siglen; +- const unsigned char* sigdata = (const unsigned char*)luaL_checklstring(L, 3, &siglen); +- const EVP_MD* md = get_digest(L, 4); ++ unsigned char* sigdata = (unsigned char*)luaL_checklstring(L, 2, &siglen); ++ const EVP_MD* md = get_digest(L, 3, NULL); ++ ASN1_BIT_STRING *sig = NULL; ++ X509_ALGOR *alg = NULL; + ++ luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!"); ++ ++ X509_REQ_get0_signature(csr, (const ASN1_BIT_STRING **)&sig, (const X509_ALGOR **)&alg); + /* (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) ? V_ASN1_NULL : V_ASN1_UNDEF, */ +- X509_ALGOR_set0(csr->sig_alg, OBJ_nid2obj(md->pkey_type), V_ASN1_NULL, NULL); ++ X509_ALGOR_set0((X509_ALGOR *)alg, OBJ_nid2obj(EVP_MD_pkey_type(md)), V_ASN1_NULL, NULL); + +- if (csr->signature->data != NULL) +- OPENSSL_free(csr->signature->data); +- csr->signature->data = OPENSSL_malloc(siglen); +- memcpy(csr->signature->data, sigdata, siglen); +- csr->signature->length = siglen; ++ ASN1_BIT_STRING_set((ASN1_BIT_STRING *)sig, sigdata, siglen); + /* + * In the interests of compatibility, I'll make sure that the bit string + * has a 'not-used bits' value of 0 + */ +- csr->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); +- csr->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; ++ sig->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); ++ sig->flags |= ASN1_STRING_FLAG_BITS_LEFT; + lua_pushboolean(L, 1); + return 1; + } ++ else ++ { ++ int inl; ++ unsigned char* tosign = NULL; ++ luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!"); ++ ++ inl = i2d_re_X509_REQ_tbs(csr, &tosign); ++ if (inl > 0 && tosign) ++ { ++ lua_pushlstring(L, (const char*)tosign, inl); ++ OPENSSL_free(tosign); ++ return 1; ++ } ++ return openssl_pushresult(L, 0); ++ } + } + ++/*** ++parse x509_req object as table ++@function parse ++@tparam[opt=true] shortname default will use short object name ++@treturn table result ++*/ + static LUA_FUNCTION(openssl_csr_parse) + { +- X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +- +- X509_NAME * subject = X509_REQ_get_subject_name(csr); ++ X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); ++ X509_NAME *subject = X509_REQ_get_subject_name(csr); + STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(csr); + + lua_newtable(L); ++ { ++ const ASN1_BIT_STRING *sig = NULL; ++ const X509_ALGOR *alg = NULL; + +- openssl_push_asn1(L, csr->signature, V_ASN1_BIT_STRING); +- lua_setfield(L, -2, "signature"); +- +- openssl_push_x509_algor(L, csr->sig_alg); +- lua_setfield(L, -2, "sig_alg"); ++ X509_REQ_get0_signature(csr, &sig, &alg); ++ openssl_push_asn1(L, sig, V_ASN1_BIT_STRING); ++ lua_setfield(L, -2, "signature"); ++ ++ alg = X509_ALGOR_dup((X509_ALGOR *)alg); ++ PUSH_OBJECT(alg, "openssl.x509_algor"); ++ lua_setfield(L, -2, "sig_alg"); ++ } + + lua_newtable(L); + AUXILIAR_SET(L, -1, "version", X509_REQ_get_version(csr), integer); +@@ -341,14 +451,16 @@ static LUA_FUNCTION(openssl_csr_parse) + } + + { +- X509_REQ_INFO* ri = csr->req_info; +- int i, c; ++ X509_PUBKEY *xpub = X509_REQ_get_X509_PUBKEY(csr); ++ ASN1_OBJECT *oalg = NULL; ++ int c; + EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr); + + lua_newtable(L); + c = X509_REQ_get_attr_count(csr); + if (c > 0) + { ++ int i; + lua_newtable(L); + for (i = 0; i < c ; i++) + { +@@ -361,10 +473,13 @@ static LUA_FUNCTION(openssl_csr_parse) + } + + lua_newtable(L); +- openssl_push_asn1object(L, ri->pubkey->algor->algorithm); +- lua_setfield(L, -2, "algorithm"); ++ if (X509_PUBKEY_get0_param(&oalg, NULL, NULL, NULL, xpub)) ++ { ++ openssl_push_asn1object(L, oalg); ++ lua_setfield(L, -2, "algorithm"); ++ } + +- AUXILIAR_SETOBJECT(L, pubkey , "openssl.evp_pkey", -1, "pubkey"); ++ AUXILIAR_SETOBJECT(L, pubkey, "openssl.evp_pkey", -1, "pubkey"); + lua_setfield(L, -2, "pubkey"); + + lua_setfield(L, -2, "req_info"); +@@ -380,6 +495,18 @@ static LUA_FUNCTION(openssl_csr_free) + return 0; + } + ++/*** ++get public key ++@function public ++@treturn evp_pkey public key ++*/ ++ ++/*** ++set public key ++@function public ++@tparam evp_pkey pubkey public key set to x509_req ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_csr_public) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +@@ -397,6 +524,17 @@ static LUA_FUNCTION(openssl_csr_public) + } + } + ++/*** ++get version key ++@function version ++@treturn integer ++*/ ++/*** ++set version key ++@function version ++@tparam integer version ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_csr_version) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +@@ -413,6 +551,17 @@ static LUA_FUNCTION(openssl_csr_version) + } + } + ++/*** ++get subject x509_name object ++@function subject ++@treturn x509_name ++*/ ++/*** ++set subject x509_name object ++@function subject ++@tparam x509_name subject ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_csr_subject) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +@@ -433,6 +582,19 @@ static LUA_FUNCTION(openssl_csr_subject) + } + } + ++/*** ++get extensions of x509_req object ++@function extensions ++@tparam[opt=false] boolean asobject, true for return as stack_of_x509_extension or as table ++@treturn stack_of_x509_extension object when param set true ++@treturn table contain all x509_extension when param set false or nothing ++*/ ++/*** ++set extension of x509_req object ++@function extensions ++@tparam stack_of_x509_extension extensions ++@treturn boolean result true for success ++*/ + static LUA_FUNCTION(openssl_csr_extensions) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +@@ -457,10 +619,29 @@ static LUA_FUNCTION(openssl_csr_extensio + } + } + ++/*** ++remove attribute object from location ++@function attribute ++@tparam integer location ++@tparam nil nil, nil not none ++@treturn x509_attribute attribute removed ++*/ ++/*** ++get attribute object from location ++@function attribute ++@tparam integer location ++@treturn x509_attribute attribute ++*/ ++/*** ++add attribute to x509_req object ++@function attribute ++@tparam x509_attribute attribute attribute to add ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_csr_attribute) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +- if (auxiliar_isclass(L, "openssl.x509_attribute", 2)) ++ if (auxiliar_getclassudata(L, "openssl.x509_attribute", 2)) + { + X509_ATTRIBUTE *attr = CHECK_OBJECT(2, X509_ATTRIBUTE, "openssl.x509_attribute"); + int ret = X509_REQ_add1_attr(csr, attr); +@@ -517,6 +698,11 @@ static LUA_FUNCTION(openssl_csr_attribut + return 0; + } + ++/*** ++get total attribute count in x509_req object ++@function attr_count ++@treturn integer ++*/ + static LUA_FUNCTION(openssl_csr_attr_count) + { + X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); +@@ -553,14 +739,6 @@ static luaL_Reg csr_cfuns[] = + {NULL, NULL } + }; + +-static luaL_Reg R[] = +-{ +- {"new", openssl_csr_new }, +- {"read", openssl_csr_read }, +- +- {NULL, NULL} +-}; +- + int luaopen_x509_req(lua_State *L) + { + auxiliar_newclass(L, "openssl.x509_req", csr_cfuns); +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/dh.c luvi-src-v2.7.6/deps/lua-openssl/src/dh.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/dh.c 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/dh.c 2019-02-13 11:53:24.275126573 +0100 +@@ -7,19 +7,12 @@ + #include "openssl.h" + #include "private.h" + #include ++#include + + #define MYNAME "dh" + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + +-#define lua_boxpointer(L,u) \ +- (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u)) +- +-#define PUSH_BN(x) \ +-lua_boxpointer(L,x); \ +-luaL_getmetatable(L,"openssl.bn"); \ +-lua_setmetatable(L,-2) +- + static LUA_FUNCTION(openssl_dh_free) + { + DH* dh = CHECK_OBJECT(1, DH, "openssl.dh"); +@@ -29,19 +22,45 @@ static LUA_FUNCTION(openssl_dh_free) + + static LUA_FUNCTION(openssl_dh_parse) + { ++ const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *pri = NULL; + DH* dh = CHECK_OBJECT(1, DH, "openssl.dh"); + lua_newtable(L); +- OPENSSL_PKEY_GET_BN(dh->p, p); +- OPENSSL_PKEY_GET_BN(dh->g, g); +- OPENSSL_PKEY_GET_BN(dh->priv_key, priv_key); +- OPENSSL_PKEY_GET_BN(dh->pub_key, pub_key); ++ ++ lua_pushinteger(L, DH_size(dh)); ++ lua_setfield(L, -2, "size"); ++ ++ lua_pushinteger(L, DH_bits(dh)); ++ lua_setfield(L, -2, "bits"); ++ ++ DH_get0_pqg(dh, &p, &q, &g); ++ DH_get0_key(dh, &pub, &pri); ++ ++ OPENSSL_PKEY_GET_BN(p, p); ++ OPENSSL_PKEY_GET_BN(q, q); ++ OPENSSL_PKEY_GET_BN(g, g); ++ OPENSSL_PKEY_GET_BN(pub, pub_key); ++ OPENSSL_PKEY_GET_BN(pri, priv_key); + + return 1; + } + ++static int openssl_dh_set_method(lua_State *L) ++{ ++ DH* dh = CHECK_OBJECT(1, DH, "openssl.dh"); ++ ENGINE *e = CHECK_OBJECT(2, ENGINE, "openssl.engine"); ++ const DH_METHOD *m = ENGINE_get_DH(e); ++ if (m) ++ { ++ int r = DH_set_method(dh, m); ++ return openssl_pushresult(L, r); ++ } ++ return 0; ++} ++ + static luaL_Reg dh_funs[] = + { + {"parse", openssl_dh_parse}, ++ {"set_method", openssl_dh_set_method}, + + {"__gc", openssl_dh_free}, + {"__tostring", auxiliar_tostring}, +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/digest.c luvi-src-v2.7.6/deps/lua-openssl/src/digest.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/digest.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/digest.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,17 +1,27 @@ +-/*=========================================================================*\ +-* digest.c +-* digest module for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++digest module for lua-openssl binding + ++@module digest ++@usage ++ digest = require('openssl').digest ++*/ + #include "openssl.h" + #include "private.h" ++#if defined(LIBRESSL_VERSION_NUMBER) ++#include ++#endif + + #define MYNAME "digest" + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + ++/*** ++list all support digest algs ++ ++@function list ++@tparam[opt] boolean alias include alias names for digest alg, default true ++@treturn[table] all methods ++*/ + static LUA_FUNCTION(openssl_digest_list) + { + int aliases = lua_isnoneornil(L, 1) ? 1 : lua_toboolean(L, 1); +@@ -20,26 +30,43 @@ static LUA_FUNCTION(openssl_digest_list) + return 1; + }; + ++/*** ++get evp_digest object ++ ++@function get ++@tparam string|integer|asn1_object alg name, nid or object identity ++@treturn evp_digest digest object mapping EVP_MD in openssl ++ ++@see evp_digest ++*/ + static LUA_FUNCTION(openssl_digest_get) + { +- const EVP_MD* md = get_digest(L, 1); ++ const EVP_MD* md = get_digest(L, 1, NULL); + +- if (md) +- PUSH_OBJECT((void*)md, "openssl.evp_digest"); +- else +- lua_pushnil(L); ++ PUSH_OBJECT((void*)md, "openssl.evp_digest"); + return 1; + } + ++/*** ++get evp_digest_ctx object ++ ++@function new ++@tparam string|integer|asn1_object alg name, nid or object identity ++@treturn evp_digest_ctx digest object mapping EVP_MD_CTX in openssl ++ ++@see evp_digest_ctx ++*/ + static LUA_FUNCTION(openssl_digest_new) + { +- const EVP_MD* md = get_digest(L, 1); +- if (md) ++ const EVP_MD* md = get_digest(L, 1, NULL); ++ int ret; ++ ENGINE* e = lua_isnoneornil(L, 2) ? NULL : CHECK_OBJECT(2, ENGINE, "openssl.engine"); ++ EVP_MD_CTX* ctx = EVP_MD_CTX_create(); ++ if (ctx!=NULL) + { +- int ret; +- ENGINE* e = (!lua_isnoneornil(L, 2)) ? CHECK_OBJECT(2, ENGINE, "openssl.engine") : NULL; +- EVP_MD_CTX* ctx = EVP_MD_CTX_create(); + EVP_MD_CTX_init(ctx); ++ lua_pushlightuserdata(L, e); ++ lua_rawsetp(L, LUA_REGISTRYINDEX, ctx); + ret = EVP_DigestInit_ex(ctx, md, e); + if (ret == 1) + { +@@ -50,15 +77,30 @@ static LUA_FUNCTION(openssl_digest_new) + EVP_MD_CTX_destroy(ctx); + return openssl_pushresult(L, ret); + } +- } +- else ++ }else + lua_pushnil(L); + return 1; + } + ++/*** ++quick method to generate digest result ++ ++@function digest ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam string msg to compute digest ++@tparam[opt] boolean raw binary result return if set true, or hex encoded string default ++@treturn string digest result value ++*/ + static LUA_FUNCTION(openssl_digest) + { +- const EVP_MD *md = NULL; ++ const EVP_MD *md; ++ ENGINE *eng; ++ size_t inl; ++ const char* in; ++ unsigned char buf[EVP_MAX_MD_SIZE]; ++ unsigned int blen = sizeof(buf); ++ int raw, status; ++ + if (lua_istable(L, 1)) + { + if (lua_getmetatable(L, 1) && lua_equal(L, 1, -1)) +@@ -69,45 +111,106 @@ static LUA_FUNCTION(openssl_digest) + else + luaL_error(L, "call function with invalid state"); + } +- if (lua_isstring(L, 1)) ++ ++ md = get_digest(L, 1, NULL); ++ in = luaL_checklstring(L, 2, &inl); ++ raw = (lua_isnoneornil(L, 3)) ? 0 : lua_toboolean(L, 3); ++ eng = (lua_isnoneornil(L, 4) ? 0 : CHECK_OBJECT(4, ENGINE, "openssl.engine")); ++ ++ status = EVP_Digest(in, inl, buf, &blen, md, eng); ++ if (status) + { +- md = EVP_get_digestbyname(lua_tostring(L, 1)); ++ if (raw) ++ lua_pushlstring(L, (const char*)buf, blen); ++ else ++ { ++ char hex[2 * EVP_MAX_MD_SIZE + 1]; ++ to_hex((const char*)buf, blen, hex); ++ lua_pushstring(L, hex); ++ } + } +- else if (auxiliar_isclass(L, "openssl.evp_digest", 1)) ++ else ++ luaL_error(L, "EVP_Digest method fail"); ++ return 1; ++}; ++ ++/*** ++create digest object for sign ++ ++@function signInit ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam[opt=nil] engine object ++@treturn evp_digest_ctx ++*/ ++static LUA_FUNCTION(openssl_signInit) ++{ ++ const EVP_MD *md = get_digest(L, 1, NULL); ++ EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); ++ ENGINE* e = lua_gettop(L) > 2 ? CHECK_OBJECT(3, ENGINE, "openssl.engine") : NULL; ++ EVP_MD_CTX *ctx = EVP_MD_CTX_create(); ++ if (ctx) + { +- md = CHECK_OBJECT(1, EVP_MD, "openssl.evp_digest"); ++ int ret; ++ EVP_MD_CTX_init(ctx); ++ ret = EVP_DigestSignInit(ctx, NULL, md, e, pkey); ++ if (ret) ++ { ++ PUSH_OBJECT(ctx, "openssl.evp_digest_ctx"); ++ } ++ else ++ return openssl_pushresult(L, ret); + } + else +- luaL_error(L, "argument #1 must be a string identity digest method or an openssl.evp_digest object"); ++ lua_pushnil(L); ++ return 1; ++} ++ ++/*** ++create digest object for verify + +- if (md) ++@function verifyInit ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam[opt=nil] engine object ++@treturn evp_digest_ctx ++*/ ++static LUA_FUNCTION(openssl_verifyInit) ++{ ++ const EVP_MD *md = get_digest(L, 1, NULL); ++ EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); ++ ENGINE* e = lua_gettop(L) > 2 ? CHECK_OBJECT(3, ENGINE, "openssl.engine") : NULL; ++ EVP_PKEY_CTX *pctx = 0; ++ EVP_MD_CTX *ctx = EVP_MD_CTX_create(); ++ ++ if (ctx) + { +- size_t inl; +- unsigned char buf[EVP_MAX_MD_SIZE]; +- unsigned int blen = sizeof(buf); +- const char* in = luaL_checklstring(L, 2, &inl); +- int raw = (lua_isnoneornil(L, 3)) ? 0 : lua_toboolean(L, 3); +- int status = EVP_Digest(in, inl, buf, &blen, md, NULL); +- if (status) ++ int ret; ++ EVP_MD_CTX_init(ctx); ++ ret = EVP_DigestVerifyInit(ctx, &pctx, md, e, pkey); ++ if (ret) + { +- if (raw) +- lua_pushlstring(L, (const char*)buf, blen); +- else +- { +- char hex[2 * EVP_MAX_MD_SIZE + 1]; +- to_hex((const char*) buf, blen, hex); +- lua_pushstring(L, hex); +- } ++ PUSH_OBJECT(ctx, "openssl.evp_digest_ctx"); + } + else +- luaL_error(L, "EVP_Digest method fail"); ++ return openssl_pushresult(L, ret); + } + else +- luaL_error(L, "argument #1 is not a valid digest algorithm or openssl.evp_digest object"); ++ lua_pushnil(L); + return 1; +-}; ++} + +-/*** evp_digest method ***/ ++/*** ++openssl.evp_digest object ++@type evp_digest ++*/ ++ ++/*** ++compute msg digest result ++ ++@function digest ++@tparam string msg data to digest ++@tparam[opt] engine, eng ++@treturn string result a binary hash value for msg ++*/ + static LUA_FUNCTION(openssl_digest_digest) + { + size_t inl; +@@ -128,6 +231,12 @@ static LUA_FUNCTION(openssl_digest_diges + return 1; + } + ++/*** ++get infomation of evp_digest object ++ ++@function info ++@treturn table info keys include nid,name size,block_size,pkey_type,flags ++*/ + static LUA_FUNCTION(openssl_digest_info) + { + EVP_MD *md = CHECK_OBJECT(1, EVP_MD, "openssl.evp_digest"); +@@ -142,10 +251,18 @@ static LUA_FUNCTION(openssl_digest_info) + return 1; + } + ++/*** ++create new evp_digest_ctx ++ ++@function new ++@tparam[opt] engine, eng ++@treturn evp_digest_ctx ctx ++@see evp_digest_ctx ++*/ + static LUA_FUNCTION(openssl_evp_digest_init) + { + EVP_MD* md = CHECK_OBJECT(1, EVP_MD, "openssl.evp_digest"); +- ENGINE* e = lua_gettop(L) > 1 ? CHECK_OBJECT(2, ENGINE, "openssl.engine") : NULL; ++ ENGINE* e = lua_isnoneornil(L, 2) ? NULL : CHECK_OBJECT(2, ENGINE, "openssl.engine"); + + EVP_MD_CTX* ctx = EVP_MD_CTX_create(); + if (ctx) +@@ -168,8 +285,33 @@ static LUA_FUNCTION(openssl_evp_digest_i + return 1; + } + +-/** openssl.evp_digest_ctx method */ ++/*** ++create digest object for sign + ++@function signInit ++@tparam[opt=nil] engine object ++@treturn evp_digest_ctx ++*/ ++ ++/*** ++create digest object for verify ++ ++@function verifyInit ++@tparam[opt=nil] engine object ++@treturn evp_digest_ctx ++*/ ++ ++/*** ++openssl.evp_digest_ctx object ++@type evp_digest_ctx ++*/ ++ ++/*** ++get infomation of evp_digest_ctx object ++ ++@function info ++@treturn table info keys include size,block_size,digest ++*/ + static LUA_FUNCTION(openssl_digest_ctx_info) + { + EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); +@@ -182,7 +324,13 @@ static LUA_FUNCTION(openssl_digest_ctx_i + return 1; + } + ++/*** ++feed data to do digest + ++@function update ++@tparam string msg data ++@treturn boolean result true for success ++*/ + static LUA_FUNCTION(openssl_evp_digest_update) + { + size_t inl; +@@ -195,6 +343,14 @@ static LUA_FUNCTION(openssl_evp_digest_u + return 1; + } + ++/*** ++get result of digest ++ ++@function final ++@tparam[opt] string last last part of data ++@tparam[opt] boolean raw binary or hex encoded result, default true for binary result ++@treturn string val hash result ++*/ + static LUA_FUNCTION(openssl_evp_digest_final) + { + EVP_MD_CTX* c = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); +@@ -248,16 +404,28 @@ static LUA_FUNCTION(openssl_evp_digest_f + static LUA_FUNCTION(openssl_digest_ctx_free) + { + EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); ++ lua_pushnil(L); ++ lua_rawsetp(L, LUA_REGISTRYINDEX, ctx); + EVP_MD_CTX_destroy(ctx); + return 0; + } + ++/*** ++reset evp_diget_ctx to reuse ++ ++@function reset ++*/ + static LUA_FUNCTION(openssl_digest_ctx_reset) + { + EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); + const EVP_MD *md = EVP_MD_CTX_md(ctx); +- ENGINE* e = ctx->engine; +- int ret = EVP_MD_CTX_cleanup(ctx); ++ ++ ENGINE* e = NULL; ++ int ret; ++ ++ lua_rawgetp(L, LUA_REGISTRYINDEX, ctx); ++ e = (ENGINE*)lua_topointer(L, -1); ++ ret = EVP_MD_CTX_reset(ctx); + if (ret) + { + EVP_MD_CTX_init(ctx); +@@ -266,6 +434,11 @@ static LUA_FUNCTION(openssl_digest_ctx_r + return openssl_pushresult(L, ret); + } + ++/*** ++clone evp_diget_ctx ++ ++@function clone ++*/ + static LUA_FUNCTION(openssl_digest_ctx_clone) + { + EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); +@@ -289,9 +462,23 @@ static LUA_FUNCTION(openssl_digest_ctx_c + return 1; + } + ++/*** ++retrieve md data ++ ++@function data ++@treturn string md_data ++*/ ++ ++/*** ++restore md data ++ ++@function data ++@tparam string md_data ++*/ + static LUA_FUNCTION(openssl_digest_ctx_data) + { + EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + if (lua_isnone(L, 2)) + { + lua_pushlstring(L, ctx->md_data, ctx->digest->ctx_size); +@@ -308,55 +495,34 @@ static LUA_FUNCTION(openssl_digest_ctx_d + else + luaL_error(L, "data with wrong data"); + } +- +- return 0; +-} +- +-static LUA_FUNCTION(openssl_signInit) +-{ +- const EVP_MD *md = get_digest(L, 1); +- EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); +- ENGINE* e = lua_gettop(L) > 2 ? CHECK_OBJECT(3, ENGINE, "openssl.engine") : NULL; +- EVP_PKEY_CTX *pctx; +- EVP_MD_CTX *ctx = EVP_MD_CTX_create(); +- if (ctx) ++#else ++ size_t ctx_size = EVP_MD_meth_get_app_datasize(EVP_MD_CTX_md(ctx)); ++ if (lua_isnone(L, 2)) + { +- int ret = EVP_DigestSignInit(ctx, &pctx, md, e, pkey); +- if (ret) +- { +- PUSH_OBJECT(ctx, "openssl.evp_digest_ctx"); +- } +- else +- return openssl_pushresult(L, ret); ++ lua_pushlstring(L, EVP_MD_CTX_md_data(ctx), ctx_size); ++ return 1; + } + else +- lua_pushnil(L); +- return 1; +-} +- +-static LUA_FUNCTION(openssl_verifyInit) +-{ +- const EVP_MD *md = get_digest(L, 1); +- EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); +- ENGINE* e = lua_gettop(L) > 2 ? CHECK_OBJECT(3, ENGINE, "openssl.engine") : NULL; +- EVP_PKEY_CTX *pctx = 0; +- EVP_MD_CTX *ctx = EVP_MD_CTX_create(); +- luaL_argcheck(L, !openssl_pkey_is_private(pkey), 2, "need public key"); +- if (ctx) + { +- int ret = EVP_DigestVerifyInit(ctx, &pctx, md, e, pkey); +- if (ret) ++ const char* d = luaL_checklstring(L, 2, &ctx_size); ++ if (ctx_size == (size_t)EVP_MD_meth_get_app_datasize(EVP_MD_CTX_md(ctx))) + { +- PUSH_OBJECT(ctx, "openssl.evp_digest_ctx"); ++ memcpy(EVP_MD_CTX_md_data(ctx), d, ctx_size); + } + else +- return openssl_pushresult(L, ret); ++ luaL_error(L, "data with wrong data"); + } +- else +- lua_pushnil(L); +- return 1; ++#endif ++ return 0; + } + ++/*** ++feed data for sign to get signature ++ ++@function verifyUpdate ++@tparam string data to be signed ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_signUpdate) + { + size_t l; +@@ -367,6 +533,13 @@ static LUA_FUNCTION(openssl_signUpdate) + return openssl_pushresult(L, ret); + } + ++/*** ++feed data for verify with signature ++ ++@function verifyUpdate ++@tparam string data to be verified ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_verifyUpdate) + { + size_t l; +@@ -377,6 +550,13 @@ static LUA_FUNCTION(openssl_verifyUpdate + return openssl_pushresult(L, ret); + } + ++/*** ++get result of sign ++ ++@function signFinal ++@tparam evp_pkey private key to do sign ++@treturn string singed result ++*/ + static LUA_FUNCTION(openssl_signFinal) + { + EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); +@@ -393,12 +573,19 @@ static LUA_FUNCTION(openssl_signFinal) + lua_pushlstring(L, (char *)sigbuf, siglen); + } + free(sigbuf); +- EVP_MD_CTX_cleanup(ctx); ++ EVP_MD_CTX_reset(ctx); + if (ret == 1) + return 1; + return openssl_pushresult(L, ret); + } + ++/*** ++get verify result ++ ++@function verifyFinal ++@tparam string signature ++@treturn boolean result, true for verify pass ++*/ + static LUA_FUNCTION(openssl_verifyFinal) + { + EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); +@@ -409,9 +596,9 @@ static LUA_FUNCTION(openssl_verifyFinal) + if (pkey) + ret = EVP_VerifyFinal(ctx, (const unsigned char*) signature, signature_len, pkey); + else +- ret = EVP_DigestVerifyFinal(ctx, (const unsigned char*) signature, signature_len); ++ ret = EVP_DigestVerifyFinal(ctx, (unsigned char*) signature, signature_len); + +- EVP_MD_CTX_cleanup(ctx); ++ EVP_MD_CTX_reset(ctx); + return openssl_pushresult(L, ret); + } + +@@ -442,7 +629,7 @@ static luaL_Reg digest_ctx_funs[] = + + {"signUpdate", openssl_signUpdate}, + {"signFinal", openssl_signFinal}, +- {"verifyUpdate", openssl_verifyUpdate}, ++ {"verifyUpdate",openssl_verifyUpdate}, + {"verifyFinal", openssl_verifyFinal}, + + {"__tostring", auxiliar_tostring}, +@@ -452,13 +639,13 @@ static luaL_Reg digest_ctx_funs[] = + + static const luaL_Reg R[] = + { +- { "__call", openssl_digest}, +- { "list", openssl_digest_list}, +- { "get", openssl_digest_get}, +- { "new", openssl_digest_new}, +- { "digest", openssl_digest}, ++ {"__call", openssl_digest}, ++ {"list", openssl_digest_list}, ++ {"get", openssl_digest_get}, ++ {"new", openssl_digest_new}, ++ {"digest", openssl_digest}, + +- {"signInit", openssl_signInit}, ++ {"signInit", openssl_signInit}, + {"verifyInit", openssl_verifyInit}, + + {NULL, NULL} +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/dsa.c luvi-src-v2.7.6/deps/lua-openssl/src/dsa.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/dsa.c 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/dsa.c 2019-02-13 11:53:24.275126573 +0100 +@@ -7,19 +7,12 @@ + #include "openssl.h" + #include "private.h" + #include ++#include + + #define MYNAME "dsa" + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + +-#define lua_boxpointer(L,u) \ +- (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u)) +- +-#define PUSH_BN(x) \ +-lua_boxpointer(L,x); \ +-luaL_getmetatable(L,"openssl.bn"); \ +-lua_setmetatable(L,-2) +- + static LUA_FUNCTION(openssl_dsa_free) + { + DSA* dsa = CHECK_OBJECT(1, DSA, "openssl.dsa"); +@@ -29,19 +22,44 @@ static LUA_FUNCTION(openssl_dsa_free) + + static LUA_FUNCTION(openssl_dsa_parse) + { ++ const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *pri = NULL; + DSA* dsa = CHECK_OBJECT(1, DSA, "openssl.rsa"); + lua_newtable(L); +- OPENSSL_PKEY_GET_BN(dsa->p, p); +- OPENSSL_PKEY_GET_BN(dsa->q, q); +- OPENSSL_PKEY_GET_BN(dsa->g, g); +- OPENSSL_PKEY_GET_BN(dsa->priv_key, priv_key); +- OPENSSL_PKEY_GET_BN(dsa->pub_key, pub_key); ++ ++ lua_pushinteger(L, DSA_size(dsa)); ++ lua_setfield(L, -2, "size"); ++ ++ lua_pushinteger(L, DSA_bits(dsa)); ++ lua_setfield(L, -2, "bits"); ++ ++ DSA_get0_pqg(dsa, &p, &q, &g); ++ DSA_get0_key(dsa, &pub, &pri); ++ ++ OPENSSL_PKEY_GET_BN(p, p); ++ OPENSSL_PKEY_GET_BN(q, q); ++ OPENSSL_PKEY_GET_BN(g, g); ++ OPENSSL_PKEY_GET_BN(pri, priv_key); ++ OPENSSL_PKEY_GET_BN(pub, pub_key); + return 1; + } + ++static int openssl_dsa_set_method(lua_State *L) ++{ ++ DSA* dsa = CHECK_OBJECT(1, DSA, "openssl.dsa"); ++ ENGINE *e = CHECK_OBJECT(2, ENGINE, "openssl.engine"); ++ const DSA_METHOD *m = ENGINE_get_DSA(e); ++ if (m) ++ { ++ int r = DSA_set_method(dsa, m); ++ return openssl_pushresult(L, r); ++ } ++ return 0; ++} ++ + static luaL_Reg dsa_funs[] = + { + {"parse", openssl_dsa_parse}, ++ {"set_method", openssl_dsa_set_method}, + + {"__gc", openssl_dsa_free}, + {"__tostring", auxiliar_tostring}, +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/ec.c luvi-src-v2.7.6/deps/lua-openssl/src/ec.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/ec.c 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/ec.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,25 +1,15 @@ +-/*=========================================================================*\ +-* ec.c +-* EC routines for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++ec module for lua-openssl binding ++@module ec ++*/ + #include "openssl.h" + #include "private.h" ++#include + + #define MYNAME "ec" + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + +-#define lua_boxpointer(L,u) \ +- (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u)) +- +-#define PUSH_BN(x) \ +-lua_boxpointer(L,x); \ +-luaL_getmetatable(L,"openssl.bn"); \ +-lua_setmetatable(L,-2); +- +- + #ifndef OPENSSL_NO_EC + + static int openssl_ecpoint_affine_coordinates(lua_State *L) +@@ -57,6 +47,7 @@ static int openssl_eckey_group(lua_State + { + const EC_POINT* p = EC_GROUP_get0_generator(g); + p = EC_POINT_dup(p, g); ++ g = EC_GROUP_dup(g); + PUSH_OBJECT(g, "openssl.ec_group"); + PUSH_OBJECT(p, "openssl.ec_point"); + return 2; +@@ -149,6 +140,22 @@ static int openssl_ec_group_asn1_flag(lu + return 0; + } + ++static point_conversion_form_t openssl_point_conversion_form(lua_State *L, int i, const char* defval) ++{ ++ const char* options[] = {"compressed", "uncompressed", "hybrid", NULL}; ++ int f = luaL_checkoption(L, 2, defval, options); ++ point_conversion_form_t form = 0; ++ if (f == 0) ++ form = POINT_CONVERSION_COMPRESSED; ++ else if (f == 1) ++ form = POINT_CONVERSION_UNCOMPRESSED; ++ else if (f == 2) ++ form = POINT_CONVERSION_HYBRID; ++ else ++ luaL_argerror(L, i, "not accept value point_conversion_form"); ++ return form; ++} ++ + static int openssl_ec_group_point_conversion_form(lua_State*L) + { + EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group"); +@@ -169,16 +176,7 @@ static int openssl_ec_group_point_conver + } + else if (lua_isstring(L, 2)) + { +- const char* options[] = {"compressed", "uncompressed", "hybrid", NULL}; +- int f = luaL_checkoption(L, 2, NULL, options); +- if (f == 0) +- form = POINT_CONVERSION_COMPRESSED; +- else if (f == 1) +- form = POINT_CONVERSION_UNCOMPRESSED; +- else if (f == 2) +- form = POINT_CONVERSION_HYBRID; +- else +- luaL_argerror(L, 2, "not accept value point_conversion_form"); ++ form = openssl_point_conversion_form(L, 2, NULL); + EC_GROUP_set_point_conversion_form(group, form); + } + else if (lua_isnumber(L, 2)) +@@ -206,7 +204,7 @@ EC_GROUP* openssl_get_ec_group(lua_State + } + else if (lua_isuserdata(L, ec_name_idx)) + { +- if (auxiliar_isclass(L, "openssl.evp_pkey", ec_name_idx)) ++ if (auxiliar_getclassudata(L, "openssl.evp_pkey", ec_name_idx)) + { + EVP_PKEY* pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); + EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pkey); +@@ -216,7 +214,7 @@ EC_GROUP* openssl_get_ec_group(lua_State + EC_KEY_free(ec_key); + } + } +- else if (auxiliar_isclass(L, "openssl.ec_key", ec_name_idx)) ++ else if (auxiliar_getclassudata(L, "openssl.ec_key", ec_name_idx)) + { + EC_KEY* ec_key = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key"); + g = (EC_GROUP*)EC_KEY_get0_group(ec_key); +@@ -291,15 +289,131 @@ EC_GROUP* openssl_get_ec_group(lua_State + return g; + } + ++static int openssl_ec_group_point_new(lua_State *L) ++{ ++ EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group"); ++ EC_POINT* point = EC_POINT_new(group); ++ PUSH_OBJECT(point, "openssl.ec_point"); ++ return 1; ++} ++ ++static int openssl_ec_point_dup(lua_State *L) ++{ ++ const EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group"); ++ const EC_POINT* point = CHECK_OBJECT(2, EC_POINT, "openssl.ec_point"); ++ ++ EC_POINT *new = EC_POINT_dup(point, group); ++ PUSH_OBJECT(new, "openssl.ec_point"); ++ return 1; ++} ++ ++static int openssl_ec_point_oct2point(lua_State *L) ++{ ++ const EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group"); ++ size_t size = 0; ++ const unsigned char* oct = (const unsigned char*)luaL_checklstring(L, 2, &size); ++ EC_POINT* point = EC_POINT_new(group); ++ ++ int ret = EC_POINT_oct2point(group, point, oct, size, NULL); ++ if(ret==1) ++ PUSH_OBJECT(point, "openssl.ec_point"); ++ else ++ ret = openssl_pushresult(L, ret); ++ return ret; ++} ++ ++static int openssl_ec_point_point2oct(lua_State *L) ++{ ++ const EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group"); ++ const EC_POINT* point = CHECK_OBJECT(2, EC_POINT, "openssl.ec_point"); ++ point_conversion_form_t form = openssl_point_conversion_form(L, 3, NULL); ++ size_t size = EC_POINT_point2oct(group, point, form, NULL, 0, NULL); ++ if(size>0) ++ { ++ unsigned char* oct = (unsigned char*)OPENSSL_malloc(size); ++ size = EC_POINT_point2oct(group, point, form, oct, size, NULL); ++ if(size>0) ++ lua_pushlstring(L, (const char*)oct, size); ++ else ++ lua_pushnil(L); ++ OPENSSL_free(oct); ++ return 1; ++ } ++ return 0; ++} ++ ++static int openssl_ec_point_bn2point(lua_State *L) ++{ ++ const EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group"); ++ BIGNUM *bn = CHECK_OBJECT(2, BIGNUM, "openssl.bn"); ++ EC_POINT* pnt = EC_POINT_bn2point(group, bn, NULL, NULL); ++ if(pnt) ++ PUSH_OBJECT(pnt, "openssl.ec_point"); ++ else ++ lua_pushnil(L); ++ return 1; ++} ++ ++static int openssl_ec_point_point2bn(lua_State *L) ++{ ++ const EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group"); ++ const EC_POINT* point = CHECK_OBJECT(2, EC_POINT, "openssl.ec_point"); ++ point_conversion_form_t form = openssl_point_conversion_form(L, 3, NULL); ++ ++ BIGNUM *bn = EC_POINT_point2bn(group, point, form, NULL, NULL); ++ if(bn) ++ PUSH_OBJECT(bn, "openssl.bn"); ++ else ++ lua_pushnil(L); ++ return 1; ++} ++ ++static int openssl_ec_point_hex2point(lua_State *L) ++{ ++ const EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group"); ++ const char* hex = luaL_checkstring(L, 2); ++ ++ EC_POINT* pnt = EC_POINT_hex2point(group, hex, NULL, NULL); ++ if(pnt) ++ PUSH_OBJECT(pnt, "openssl.ec_point"); ++ else ++ lua_pushnil(L); ++ return 1; ++} ++ ++static int openssl_ec_point_point2hex(lua_State *L) ++{ ++ const EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group"); ++ const EC_POINT* point = CHECK_OBJECT(2, EC_POINT, "openssl.ec_point"); ++ point_conversion_form_t form = openssl_point_conversion_form(L, 3, NULL); ++ ++ const char* hex = EC_POINT_point2hex(group, point, form, NULL); ++ if(hex) ++ lua_pushstring(L, hex); ++ else ++ lua_pushnil(L); ++ return 1; ++} ++ ++ + static luaL_Reg ec_group_funs[] = + { +- {"__tostring", auxiliar_tostring}, +- {"affine_coordinates", openssl_ecpoint_affine_coordinates}, +- {"parse", openssl_ec_group_parse}, +- {"asn1_flag", openssl_ec_group_asn1_flag}, +- {"point_conversion_form", openssl_ec_group_point_conversion_form}, ++ {"__tostring", auxiliar_tostring}, ++ {"__gc", openssl_ec_group_free}, + +- {"__gc", openssl_ec_group_free}, ++ {"affine_coordinates", openssl_ecpoint_affine_coordinates}, ++ {"parse", openssl_ec_group_parse}, ++ {"asn1_flag", openssl_ec_group_asn1_flag}, ++ ++ {"point_conversion_form", openssl_ec_group_point_conversion_form}, ++ {"point_new", openssl_ec_group_point_new}, ++ {"point_dup", openssl_ec_point_dup}, ++ {"point2oct", openssl_ec_point_point2oct}, ++ {"oct2point", openssl_ec_point_oct2point}, ++ {"point2bn", openssl_ec_point_point2bn}, ++ {"bn2point", openssl_ec_point_bn2point}, ++ {"point2hex", openssl_ec_point_point2hex}, ++ {"hex2point", openssl_ec_point_hex2point}, + + { NULL, NULL } + }; +@@ -309,41 +423,89 @@ static int openssl_ecdsa_sign(lua_State* + { + EC_KEY* ec = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key"); + size_t l; +- const char* s = luaL_checklstring(L, 2, &l); +- ECDSA_SIG* sig = ECDSA_do_sign((const unsigned char*)s, l, ec); +- if (sig) ++ const char* sdata = luaL_checklstring(L, 2, &l); ++ ECDSA_SIG* sig = ECDSA_do_sign((const unsigned char*)sdata, l, ec); ++ int der = lua_isnone(L, 3) ? 1 : lua_toboolean(L, 3); ++ int ret = 0; ++ ++ if (der) + { +- PUSH_BN(BN_dup(sig->r)); +- PUSH_BN(BN_dup(sig->s)); +- ECDSA_SIG_free(sig); +- return 2; ++ unsigned char*p = NULL; ++ l = i2d_ECDSA_SIG(sig, &p); ++ if (l > 0) ++ { ++ lua_pushlstring(L, (const char*)p, l); ++ OPENSSL_free(p); ++ ret = 1; ++ } + } +- return 0; ++ else ++ { ++ const BIGNUM *r = NULL, *s = NULL; ++ ECDSA_SIG_get0(sig, &r, &s); ++ ++ r = BN_dup(r); ++ s = BN_dup(s); ++ ++ PUSH_OBJECT(r, "openssl.bn"); ++ PUSH_OBJECT(s, "openssl.bn"); ++ ret = 2; ++ } ++ ECDSA_SIG_free(sig); ++ return ret; + } + + static int openssl_ecdsa_verify(lua_State*L) + { +- size_t l; ++ size_t l, sigl; + int ret; + EC_KEY* ec = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key"); + const char* dgst = luaL_checklstring(L, 2, &l); +- BIGNUM *r = CHECK_OBJECT(3, BIGNUM, "openssl.bn"); +- BIGNUM *s = CHECK_OBJECT(4, BIGNUM, "openssl.bn"); +- +- ECDSA_SIG* sig = ECDSA_SIG_new(); +- BN_copy(sig->r, r); +- BN_copy(sig->s, s); +- +- ret = ECDSA_do_verify((const unsigned char*)dgst, l, sig, ec); +- if (ret == -1) +- lua_pushnil(L); ++ int top = lua_gettop(L); ++ if (top == 3) ++ { ++ const char* s = luaL_checklstring(L, 3, &sigl); ++ ECDSA_SIG* sig = d2i_ECDSA_SIG(NULL, (const unsigned char**)&s, sigl); ++ ret = ECDSA_do_verify((const unsigned char*)dgst, l, sig, ec); ++ if (ret == -1) ++ ret = openssl_pushresult(L, -1); ++ else ++ { ++ lua_pushboolean(L, ret); ++ ret = 1; ++ } ++ ECDSA_SIG_free(sig); ++ return ret; ++ } + else +- lua_pushboolean(L, ret); +- ECDSA_SIG_free(sig); +- return 1; ++ { ++ BIGNUM *r = BN_get(L, 3); ++ BIGNUM *s = BN_get(L, 4); ++ ECDSA_SIG* sig = ECDSA_SIG_new(); ++ ECDSA_SIG_set0(sig, r, s); ++ ret = ECDSA_do_verify((const unsigned char*)dgst, l, sig, ec); ++ if (ret == -1) ++ ret = openssl_pushresult(L, -1); ++ else ++ { ++ lua_pushboolean(L, ret); ++ ret = 1; ++ } ++ ECDSA_SIG_free(sig); ++ return ret; ++ } ++} ++ ++/* ec_point */ ++static int openssl_ec_point_copy(lua_State *L) ++{ ++ EC_POINT* self = CHECK_OBJECT(1, EC_POINT, "openssl.ec_point"); ++ EC_POINT* to = CHECK_OBJECT(2, EC_POINT, "openssl.ec_point"); ++ int ret = EC_POINT_copy(to, self); ++ return openssl_pushresult(L, ret); + } + +-static int openssl_ec_point_free(lua_State*L) ++static int openssl_ec_point_free(lua_State *L) + { + EC_POINT* p = CHECK_OBJECT(1, EC_POINT, "openssl.ec_point"); + EC_POINT_free(p); +@@ -398,11 +560,119 @@ static int openssl_ec_key_parse(lua_Stat + return 1; + }; + ++# ifndef OPENSSL_NO_ECDH ++static const int KDF1_SHA1_len = 20; ++static void *KDF1_SHA1(const void *in, size_t inlen, void *out, ++ size_t *outlen) ++{ ++# ifndef OPENSSL_NO_SHA ++ if (*outlen < SHA_DIGEST_LENGTH) ++ return NULL; ++ else ++ *outlen = SHA_DIGEST_LENGTH; ++ return SHA1(in, inlen, out); ++# else ++ return NULL; ++# endif /* OPENSSL_NO_SHA */ ++} ++# endif /* OPENSSL_NO_ECDH */ ++ ++# define MAX_ECDH_SIZE 256 ++ ++static int openssl_ecdh_compute_key(lua_State*L) ++{ ++ EC_KEY *ec = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key"); ++ EC_KEY *peer = CHECK_OBJECT(2, EC_KEY, "openssl.ec_key"); ++ ++ int field_size, outlen, secret_size_a; ++ unsigned char secret_a[MAX_ECDH_SIZE]; ++ void *(*kdf) (const void *in, size_t inlen, void *out, size_t *xoutlen); ++ field_size = ++ EC_GROUP_get_degree(EC_KEY_get0_group(ec)); ++ if (field_size <= 24 * 8) ++ { ++ outlen = KDF1_SHA1_len; ++ kdf = KDF1_SHA1; ++ } ++ else ++ { ++ outlen = (field_size + 7) / 8; ++ kdf = NULL; ++ } ++ secret_size_a = ++ ECDH_compute_key(secret_a, outlen, ++ EC_KEY_get0_public_key(peer), ++ ec, kdf); ++ lua_pushlstring(L, (const char*)secret_a, secret_size_a); ++ return 1; ++} ++ ++static int openssl_ecdsa_set_method(lua_State *L) ++{ ++ EC_KEY *ec = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key"); ++ ENGINE *e = CHECK_OBJECT(2, ENGINE, "openssl.engine"); ++#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L ++ const ECDSA_METHOD *m = ENGINE_get_ECDSA(e); ++ if (m) ++ { ++ int r = ECDSA_set_method(ec, m); ++ return openssl_pushresult(L, r); ++ } ++#else ++ const EC_KEY_METHOD *m = ENGINE_get_EC(e); ++ if (m) ++ { ++ int r = EC_KEY_set_method(ec, m); ++ return openssl_pushresult(L, r); ++ } ++#endif ++ return 0; ++} ++ ++static int openssl_ec_key_export(lua_State *L) ++{ ++ EC_KEY *ec = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key"); ++ unsigned char* der = NULL; ++ int len = i2d_ECPrivateKey(ec, &der); ++ if(len>0) ++ lua_pushlstring(L, (const char*)der, len); ++ else ++ lua_pushnil(L); ++ if(der) ++ OPENSSL_free(der); ++ return 1; ++} ++ ++static int openssl_ec_key_read(lua_State *L) ++{ ++ size_t len = 0; ++ const unsigned char* der = (const unsigned char*)luaL_checklstring(L, 1, &len); ++ ++ EC_KEY* ec = d2i_ECPrivateKey(NULL, &der, len); ++ if(ec) ++ PUSH_OBJECT(ec, "openssl.ec_key"); ++ else ++ lua_pushnil(L); ++ return 1; ++} ++ ++#ifdef EC_EXT ++EC_EXT_DEFINE ++#endif ++ + static luaL_Reg ec_key_funs[] = + { ++ {"export", openssl_ec_key_export}, + {"parse", openssl_ec_key_parse}, + {"sign", openssl_ecdsa_sign}, + {"verify", openssl_ecdsa_verify}, ++ {"compute_key", openssl_ecdh_compute_key}, ++ {"set_method", openssl_ecdsa_set_method}, ++ ++#ifdef EC_EXT ++ EC_EXT ++#endif ++ + {"__gc", openssl_ec_key_free}, + {"__tostring", auxiliar_tostring}, + +@@ -411,8 +681,9 @@ static luaL_Reg ec_key_funs[] = + + static luaL_Reg ec_point_funs[] = + { +- {"__tostring", auxiliar_tostring}, +- {"__gc", openssl_ec_point_free}, ++ {"__tostring", auxiliar_tostring}, ++ {"__gc", openssl_ec_point_free}, ++ {"copy", openssl_ec_point_copy}, + + { NULL, NULL } + }; +@@ -452,8 +723,9 @@ static LUA_FUNCTION(openssl_ec_list_curv + + static luaL_Reg R[] = + { +- {"list", openssl_ec_list_curve_name}, +- {"group", openssl_eckey_group}, ++ {"read", openssl_ec_key_read}, ++ {"list", openssl_ec_list_curve_name}, ++ {"group", openssl_eckey_group}, + + { NULL, NULL } + }; +@@ -462,7 +734,7 @@ int luaopen_ec(lua_State *L) + { + auxiliar_newclass(L, "openssl.ec_point", ec_point_funs); + auxiliar_newclass(L, "openssl.ec_group", ec_group_funs); +- auxiliar_newclass(L, "openssl.ec_key", ec_key_funs); ++ auxiliar_newclass(L, "openssl.ec_key", ec_key_funs); + + lua_newtable(L); + luaL_setfuncs(L, R, 0); +@@ -474,4 +746,3 @@ int luaopen_ec(lua_State *L) + } + + #endif +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/engine.c luvi-src-v2.7.6/deps/lua-openssl/src/engine.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/engine.c 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/engine.c 2019-02-13 11:53:24.275126573 +0100 +@@ -8,18 +8,28 @@ + #include + #include "openssl.h" + #include "private.h" ++#include + + enum + { + TYPE_RSA, + TYPE_DSA, ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + TYPE_ECDH, + TYPE_ECDSA, ++#else ++ TYPE_EC, ++#endif + TYPE_DH, + TYPE_RAND, +- TYPE_STORE, + TYPE_CIPHERS, + TYPE_DIGESTS, ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++ TYPE_STORE, ++#else ++ TYPE_PKEY_METHODS, ++ TYPE_PKEY_ASN1_METHODS, ++#endif + TYPE_COMPLETE + }; + +@@ -140,6 +150,7 @@ static int openssl_engine_register(lua_S + else + ENGINE_register_DSA(eng); + break; ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + case TYPE_ECDH: + if (unregister) + ENGINE_unregister_ECDH(eng); +@@ -152,6 +163,14 @@ static int openssl_engine_register(lua_S + else + ENGINE_register_ECDSA(eng); + break; ++#else ++ case TYPE_EC: ++ if (unregister) ++ ENGINE_unregister_EC(eng); ++ else ++ ENGINE_register_EC(eng); ++ break; ++#endif + case TYPE_DH: + if (unregister) + ENGINE_unregister_DH(eng); +@@ -164,12 +183,27 @@ static int openssl_engine_register(lua_S + else + ENGINE_register_RAND(eng); + break; ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + case TYPE_STORE: + if (unregister) + ENGINE_unregister_STORE(eng); + else + ENGINE_register_STORE(eng); + break; ++#else ++ case TYPE_PKEY_METHODS: ++ if (unregister) ++ ENGINE_unregister_pkey_meths(eng); ++ else ++ ENGINE_register_pkey_meths(eng); ++ break; ++ case TYPE_PKEY_ASN1_METHODS: ++ if (unregister) ++ ENGINE_unregister_pkey_asn1_meths(eng); ++ else ++ ENGINE_register_pkey_asn1_meths(eng); ++ break; ++#endif + case TYPE_CIPHERS: + if (unregister) + ENGINE_unregister_ciphers(eng); +@@ -201,22 +235,20 @@ static int openssl_engine_register(lua_S + static int openssl_engine_ctrl(lua_State*L) + { + ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); +- ++ int ret = 0; + if (lua_isnumber(L, 2)) + { + int cmd = luaL_checkint(L, 2); + if (lua_isnoneornil(L, 3)) + { +- int ret = ENGINE_cmd_is_executable(eng, cmd); +- lua_pushboolean(L, ret); ++ ret = ENGINE_cmd_is_executable(eng, cmd); + } + else + { + long i = (long)luaL_checknumber(L, 3); + void* p = lua_touserdata(L, 4); + void* arg = lua_isnoneornil(L, 5) ? NULL : lua_touserdata(L, 5); +- int ret = ENGINE_ctrl(eng, cmd, i, p, arg); +- lua_pushboolean(L, ret); ++ ret = ENGINE_ctrl(eng, cmd, i, p, arg); + } + } + else +@@ -225,27 +257,35 @@ static int openssl_engine_ctrl(lua_State + if (lua_isnumber(L, 3)) + { + long i = (long)luaL_checknumber(L, 3); +- void* p = lua_touserdata(L, 4); +- void* arg = lua_isnoneornil(L, 5) ? NULL : lua_touserdata(L, 5); +- int opt = luaL_optint(L, 6, 0); +- int ret = ENGINE_ctrl_cmd(eng, cmd, i, p, arg, opt); +- lua_pushboolean(L, ret); ++ if (lua_isstring(L, 4)) ++ { ++ const char* s = lua_tostring(L, 4); ++ void* arg = lua_isnoneornil(L, 5) ? NULL : lua_touserdata(L, 5); ++ int opt = luaL_optint(L, 6, 0); ++ ret = ENGINE_ctrl_cmd(eng, cmd, i, (void*)s, arg, opt); ++ } ++ else ++ { ++ void* p = lua_touserdata(L, 4); ++ void* arg = lua_isnoneornil(L, 5) ? NULL : lua_touserdata(L, 5); ++ int opt = luaL_optint(L, 6, 0); ++ ret = ENGINE_ctrl_cmd(eng, cmd, i, p, arg, opt); ++ } + } + else + { + const char* arg = luaL_optstring(L, 3, NULL); + int opt = luaL_optint(L, 4, 0); +- int ret = ENGINE_ctrl_cmd_string(eng, cmd, arg, opt); +- lua_pushboolean(L, ret); ++ ret = ENGINE_ctrl_cmd_string(eng, cmd, arg, opt); + } + } +- return 1; ++ return openssl_pushresult(L, ret); + } + + static int openssl_engine_gc(lua_State*L) + { + ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); +- (void*) eng; ++ (void) eng; + return 0; + } + +@@ -297,11 +337,11 @@ static int openssl_engine_flags(lua_Stat + lua_pushinteger(L, ENGINE_get_flags(eng)); + return 1; + } ++ + /* + int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); + void *ENGINE_get_ex_data(const ENGINE *e, int idx); + */ +- + static int openssl_engine_init(lua_State*L) + { + ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); +@@ -310,7 +350,6 @@ static int openssl_engine_init(lua_State + return 1; + } + +- + static int openssl_engine_finish(lua_State*L) + { + ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); +@@ -319,7 +358,6 @@ static int openssl_engine_finish(lua_Sta + return 1; + } + +- + static int openssl_engine_set_default(lua_State*L) + { + ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); +@@ -340,8 +378,7 @@ static int openssl_engine_set_default(lu + } + else + luaL_error(L, "#2 must be a number or string"); +- lua_pushboolean(L, ret); +- return 1; ++ return openssl_pushresult(L, ret); + } + + while (first <= top) +@@ -355,12 +392,18 @@ static int openssl_engine_set_default(lu + case TYPE_DSA: + ret = ENGINE_set_default_DSA(eng); + break; ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + case TYPE_ECDH: + ret = ENGINE_set_default_ECDH(eng); + break; + case TYPE_ECDSA: + ret = ENGINE_set_default_ECDSA(eng); + break; ++#else ++ case TYPE_EC: ++ ret = ENGINE_set_default_EC(eng); ++ break; ++#endif + case TYPE_DH: + ret = ENGINE_set_default_DH(eng); + break; +@@ -384,36 +427,156 @@ static int openssl_engine_set_default(lu + return 1; + } + } +- lua_pushboolean(L, ret); +- return 1; ++ return openssl_pushresult(L, ret); ++}; ++ ++static int openssl_engine_set_rand_engine(lua_State *L) ++{ ++ ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); ++ int ret = RAND_set_rand_engine(eng); ++ return openssl_pushresult(L, ret); ++} ++ ++static int openssl_engine_load_private_key(lua_State *L) ++{ ++ ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); ++ const char* key_id = luaL_checkstring(L, 2); ++ EVP_PKEY *pkey = ENGINE_load_private_key(eng, key_id, NULL, NULL); ++ if (pkey != NULL) ++ { ++ PUSH_OBJECT(pkey, "openssl.evp_pkey"); ++ return 1; ++ } ++ return openssl_pushresult(L, 0); ++} ++ ++static int openssl_engine_load_public_key(lua_State *L) ++{ ++ ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); ++ const char* key_id = luaL_checkstring(L, 2); ++ EVP_PKEY *pkey = ENGINE_load_public_key(eng, key_id, NULL, NULL); ++ if (pkey != NULL) ++ { ++ PUSH_OBJECT(pkey, "openssl.evp_pkey"); ++ return 1; ++ } ++ return openssl_pushresult(L, 0); ++} ++ ++static int openssl_engine_load_ssl_client_cert(lua_State *L) ++{ ++ ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); ++ SSL* s = CHECK_OBJECT(2, SSL, "openssl.ssl"); ++ STACK_OF(X509_NAME) *ca_dn = SSL_get_client_CA_list(s); ++ ++ X509 *pcert = NULL; ++ EVP_PKEY *pkey = NULL; ++ STACK_OF(X509) *pothers = NULL; ++ ++ int ret = ENGINE_load_ssl_client_cert(eng, s, ca_dn, ++ &pcert, &pkey, &pothers, NULL, NULL); ++ if (ret == 1) ++ { ++ PUSH_OBJECT(pcert, "openssl.x509"); ++ if (pkey != NULL) ++ { ++ PUSH_OBJECT(pkey, "openssl.pkey"); ++ ret++; ++ } ++ if (pothers != NULL) ++ { ++ openssl_sk_x509_totable(L, pothers); ++ ret++; ++ } ++ return ret; ++ } ++ return openssl_pushresult(L, 0); ++} ++ ++struct _engine_exdata ++{ ++ int l; ++ unsigned char p[1]; + }; + ++static int openssl_engine_ex_data(lua_State *L) ++{ ++ ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); ++ int idx; ++ int ret; ++ if (lua_isnoneornil(L, 2)) ++ { ++ idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, NULL); ++ if (idx == -1) ++ { ++ lua_pushnil(L); ++ return 1; ++ } ++ lua_pushinteger(L, idx); ++ return 1; ++ } ++ idx = luaL_checkinteger(L, 2); ++ if (lua_isnoneornil(L, 3)) ++ { ++ void *p = ENGINE_get_ex_data(eng, idx); ++ if (p) ++ { ++ struct _engine_exdata *ex = p; ++ lua_pushlstring(L, (const char*)ex->p, ex->l); ++ } ++ else ++ lua_pushnil(L); ++ return 1; ++ } ++ else ++ { ++ size_t l; ++ const char *s = luaL_checklstring(L, 3, &l); ++ struct _engine_exdata *ex = OPENSSL_malloc(sizeof(struct _engine_exdata)+l); ++ ex->l = l; ++ memcpy(ex->p, s, l); ++ ret = ENGINE_set_ex_data(eng, idx, ex); ++ if (ret != 1) ++ { ++ OPENSSL_free(ex); ++ lua_pushnil(L); ++ } ++ else ++ lua_pushboolean(L, 1); ++ return 1; ++ } ++} ++ + static luaL_Reg eng_funcs[] = + { + {"next", openssl_engine_next}, + {"prev", openssl_engine_prev}, + {"add", openssl_engine_add}, +- {"remove", openssl_engine_remove}, +- {"register", openssl_engine_register}, ++ {"remove", openssl_engine_remove}, ++ {"register", openssl_engine_register}, + {"ctrl", openssl_engine_ctrl}, + {"id", openssl_engine_id}, + {"name", openssl_engine_name}, + {"flags", openssl_engine_flags}, + +- {"init", openssl_engine_init}, +- {"finish", openssl_engine_finish}, ++ {"ex_data", openssl_engine_ex_data}, ++ {"set_rand_engine", openssl_engine_set_rand_engine}, ++ {"load_private_key", openssl_engine_load_private_key}, ++ {"load_public_key", openssl_engine_load_public_key }, ++ {"load_ssl_client_cert", openssl_engine_load_ssl_client_cert}, ++ ++ {"init", openssl_engine_init}, ++ {"finish", openssl_engine_finish}, + {"set_default", openssl_engine_set_default}, + +- {"__gc", openssl_engine_gc}, ++ {"__gc", openssl_engine_gc}, + {"__tostring", auxiliar_tostring}, + + {NULL, NULL}, + }; + +- + int openssl_register_engine(lua_State* L) + { + auxiliar_newclass(L, "openssl.engine", eng_funcs); + return 0; + } +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/hmac.c luvi-src-v2.7.6/deps/lua-openssl/src/hmac.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/hmac.c 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/hmac.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,33 +1,127 @@ +-/*=========================================================================*\ +-* hamc.c +-* hamc module for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++hamc module for lua-openssl binding + ++@module hmac ++@author george zhao ++@usage ++ hamc = require('openssl').hmac ++*/ + #include "openssl.h" + #include "private.h" +-#include + + #define MYNAME "hmac" + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + ++/*** ++get hamc_ctx object ++ ++@function new ++@tparam string|integer|asn1_object alg name, nid or object identity ++@tparam string key secret key ++@tparam[opt] engine engine, nothing with default engine ++@treturn hamc_ctx hmac object mapping HMAC_CTX in openssl ++ ++@see hmac_ctx ++*/ + static int openssl_hmac_new(lua_State *L) + { +- const EVP_MD *type = get_digest(L, 1); ++ const EVP_MD *type = get_digest(L, 1, NULL); + size_t l; + const char *k = luaL_checklstring(L, 2, &l); + ENGINE* e = lua_isnoneornil(L, 3) ? NULL : CHECK_OBJECT(3, ENGINE, "openssl.engine"); + +- HMAC_CTX *c = OPENSSL_malloc(sizeof(HMAC_CTX)); +- HMAC_CTX_init(c); ++ HMAC_CTX *c = HMAC_CTX_new(); + HMAC_Init_ex(c, k, (int)l, type, e); + PUSH_OBJECT(c, "openssl.hmac_ctx"); + + return 1; + } + ++static int openssl_hmac_free(lua_State *L) ++{ ++ HMAC_CTX *c = CHECK_OBJECT(1, HMAC_CTX, "openssl.hmac_ctx"); ++ if(!c) ++ return 0; ++ HMAC_CTX_free(c); ++ FREE_OBJECT(1); ++ return 0; ++} ++ ++/*** ++compute hmac one step, in module openssl.hamc ++ ++@function hmac ++@tparam evp_digest|string|nid digest digest alg identity ++@tparam string message ++@tparam string key ++@treturn string result binary string ++*/ ++/*** ++alias for hmac ++ ++@function digest ++@tparam evp_digest|string|nid digest digest alg identity ++@tparam string message ++@tparam string key ++@treturn string result binary string ++*/ ++static int openssl_hmac(lua_State *L) ++{ ++ if (lua_istable(L, 1)) ++ { ++ if (lua_getmetatable(L, 1) && lua_equal(L, 1, -1)) ++ { ++ lua_pop(L, 1); ++ lua_remove(L, 1); ++ } ++ else ++ luaL_error(L, "call function with invalid state"); ++ } ++ { ++ ++ const EVP_MD *type = get_digest(L, 1, NULL); ++ size_t len; ++ const char *dat = luaL_checklstring(L, 2, &len); ++ size_t l; ++ const char *k = luaL_checklstring(L, 3, &l); ++ int raw = (lua_isnoneornil(L, 4)) ? 0 : lua_toboolean(L, 4); ++ ENGINE* e = lua_isnoneornil(L, 5) ? NULL : CHECK_OBJECT(5, ENGINE, "openssl.engine"); ++ ++ unsigned char digest[EVP_MAX_MD_SIZE]; ++ ++ HMAC_CTX *c = HMAC_CTX_new(); ++ HMAC_Init_ex(c, k, (int)l, type, e); ++ ++ HMAC_Update(c, (unsigned char *)dat, len); ++ len = EVP_MAX_MD_SIZE; ++ HMAC_Final(c, digest, (unsigned int*)&len); ++ ++ HMAC_CTX_free(c); ++ ++ if (raw) ++ lua_pushlstring(L, (char *)digest, len); ++ else ++ { ++ char hex[2 * EVP_MAX_MD_SIZE + 1]; ++ to_hex((const char*)digest, len, hex); ++ lua_pushstring(L, hex); ++ } ++ } ++ return 1; ++} ++ ++/*** ++openssl.hmac_ctx object ++@type hmac_ctx ++*/ ++ ++/*** ++feed data to do digest ++ ++@function update ++@tparam string msg data ++*/ + static int openssl_hmac_update(lua_State *L) + { + HMAC_CTX *c = CHECK_OBJECT(1, HMAC_CTX, "openssl.hmac_ctx"); +@@ -38,6 +132,14 @@ static int openssl_hmac_update(lua_State + return 0; + } + ++/*** ++get result of hmac ++ ++@function final ++@tparam[opt] string last last part of data ++@tparam[opt] boolean raw binary or hex encoded result, default true for binary result ++@treturn string val hash result ++*/ + static int openssl_hmac_final(lua_State *L) + { + HMAC_CTX *c = CHECK_OBJECT(1, HMAC_CTX, "openssl.hmac_ctx"); +@@ -70,6 +172,11 @@ static int openssl_hmac_final(lua_State + return 1; + } + ++/*** ++reset hmac_ctx to reuse ++ ++@function reset ++*/ + static int openssl_hmac_reset(lua_State *L) + { + HMAC_CTX *c = CHECK_OBJECT(1, HMAC_CTX, "openssl.hmac_ctx"); +@@ -77,61 +184,6 @@ static int openssl_hmac_reset(lua_State + return openssl_pushresult(L, ret); + } + +-static int openssl_hmac_free(lua_State *L) +-{ +- HMAC_CTX *c = CHECK_OBJECT(1, HMAC_CTX, "openssl.hmac_ctx"); +- HMAC_CTX_cleanup(c); +- OPENSSL_free(c); +- return 0; +-} +- +-static int openssl_hmac(lua_State *L) +-{ +- if (lua_istable(L, 1)) +- { +- if (lua_getmetatable(L, 1) && lua_equal(L, 1, -1)) +- { +- lua_pop(L, 1); +- lua_remove(L, 1); +- } +- else +- luaL_error(L, "call function with invalid state"); +- } +- { +- +- const EVP_MD *type = get_digest(L, 1); +- size_t len; +- const char *dat = luaL_checklstring(L, 2, &len); +- size_t l; +- const char *k = luaL_checklstring(L, 3, &l); +- int raw = (lua_isnoneornil(L, 4)) ? 0 : lua_toboolean(L, 4); +- ENGINE* e = lua_isnoneornil(L, 5) ? NULL : CHECK_OBJECT(5, ENGINE, "openssl.engine"); +- +- unsigned char digest[EVP_MAX_MD_SIZE]; +- +- HMAC_CTX ctx; +- HMAC_CTX *c = &ctx; +- HMAC_CTX_init(c); +- HMAC_Init_ex(c, k, (int)l, type, e); +- +- HMAC_Update(c, (unsigned char *)dat, len); +- len = EVP_MAX_MD_SIZE; +- HMAC_Final(c, digest, (unsigned int*)&len); +- +- HMAC_CTX_cleanup(c); +- +- if (raw) +- lua_pushlstring(L, (char *)digest, len); +- else +- { +- char hex[2 * EVP_MAX_MD_SIZE + 1]; +- to_hex((const char*)digest, len, hex); +- lua_pushstring(L, hex); +- } +- } +- return 1; +-} +- + static luaL_Reg hmac_ctx_funs[] = + { + {"update", openssl_hmac_update}, +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/lbn.c luvi-src-v2.7.6/deps/lua-openssl/src/lbn.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/lbn.c 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/lbn.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,9 +1,10 @@ +-/* +-* lbn.c +-* big-number library for Lua 5.1 based on OpenSSL bn +-* Luiz Henrique de Figueiredo +-* 11 Nov 2010 22:56:45 +-* This code is hereby placed in the public domain. ++/*** ++big-number library for Lua 5.1 based on OpenSSL bn ++ ++@module bn ++@author Luiz Henrique de Figueiredo ++@license This code is hereby placed in the public domain. ++@warning verson 11 Nov 2010 22:56:45 + */ + + #include +@@ -22,17 +23,11 @@ + + #include "private.h" + +-#define lua_boxpointer(L,u) \ +- (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u)) +- + #define MYNAME "bn" + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2010 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + #define MYTYPE "openssl.bn" + +- +-static BN_CTX *ctx = NULL; +- + static void error(lua_State *L, const char *message) + { + luaL_error(L, "(bn) %s %s", message, ERR_reason_error_string(ERR_get_error())); +@@ -42,9 +37,7 @@ static BIGNUM *Bnew(lua_State *L) + { + BIGNUM *x = BN_new(); + if (x == NULL) error(L, "BN_new failed"); +- lua_boxpointer(L, x); +- luaL_getmetatable(L, MYTYPE); +- lua_setmetatable(L, -2); ++ PUSH_BN(x); + return x; + } + +@@ -183,7 +176,9 @@ static int Bsqr(lua_State *L) /** sq + { + BIGNUM *a = Bget(L, 1); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_sqr(c, a, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -236,7 +231,9 @@ static int Bmul(lua_State *L) /** mu + BIGNUM *a = Bget(L, 1); + BIGNUM *b = Bget(L, 2); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_mul(c, a, b, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -246,7 +243,9 @@ static int Bdiv(lua_State *L) /** di + BIGNUM *b = Bget(L, 2); + BIGNUM *q = Bnew(L); + BIGNUM *r = NULL; ++ BN_CTX *ctx = BN_CTX_new(); + BN_div(q, r, a, b, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -256,7 +255,9 @@ static int Bmod(lua_State *L) /** mo + BIGNUM *b = Bget(L, 2); + BIGNUM *q = NULL; + BIGNUM *r = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_div(q, r, a, b, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -265,7 +266,9 @@ static int Brmod(lua_State *L) /** + BIGNUM *a = Bget(L, 1); + BIGNUM *b = Bget(L, 2); + BIGNUM *r = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_nnmod(r, a, b, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -275,7 +278,9 @@ static int Bdivmod(lua_State *L) /** + BIGNUM *b = Bget(L, 2); + BIGNUM *q = Bnew(L); + BIGNUM *r = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_div(q, r, a, b, ctx); ++ BN_CTX_free(ctx); + return 2; + } + +@@ -284,7 +289,9 @@ static int Bgcd(lua_State *L) /** gc + BIGNUM *a = Bget(L, 1); + BIGNUM *b = Bget(L, 2); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_gcd(c, a, b, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -293,7 +300,9 @@ static int Bpow(lua_State *L) /** po + BIGNUM *a = Bget(L, 1); + BIGNUM *b = Bget(L, 2); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_exp(c, a, b, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -303,7 +312,9 @@ static int Baddmod(lua_State *L) /** + BIGNUM *b = Bget(L, 2); + BIGNUM *m = Bget(L, 3); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_mod_add(c, a, b, m, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -313,7 +324,9 @@ static int Bsubmod(lua_State *L) /** + BIGNUM *b = Bget(L, 2); + BIGNUM *m = Bget(L, 3); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_mod_sub(c, a, b, m, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -323,7 +336,9 @@ static int Bmulmod(lua_State *L) /** + BIGNUM *b = Bget(L, 2); + BIGNUM *m = Bget(L, 3); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_mod_mul(c, a, b, m, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -333,7 +348,9 @@ static int Bpowmod(lua_State *L) /** + BIGNUM *b = Bget(L, 2); + BIGNUM *m = Bget(L, 3); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_mod_exp(c, a, b, m, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -342,7 +359,9 @@ static int Bsqrmod(lua_State *L) /** + BIGNUM *a = Bget(L, 1); + BIGNUM *m = Bget(L, 2); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_mod_sqr(c, a, m, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -351,7 +370,9 @@ static int Binvmod(lua_State *L) /** + BIGNUM *a = Bget(L, 1); + BIGNUM *m = Bget(L, 2); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_mod_inverse(c, a, m, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -360,7 +381,9 @@ static int Bsqrtmod(lua_State *L) /** + BIGNUM *a = Bget(L, 1); + BIGNUM *m = Bget(L, 2); + BIGNUM *c = Bnew(L); ++ BN_CTX *ctx = BN_CTX_new(); + BN_mod_sqrt(c, a, m, ctx); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -387,7 +410,9 @@ static int Bisprime(lua_State *L) /** + { + int checks = luaL_optint(L, 2, BN_prime_checks); + BIGNUM *a = Bget(L, 1); ++ BN_CTX *ctx = BN_CTX_new(); + lua_pushboolean(L, BN_is_prime_fasttest_ex(a, checks, ctx, 1, NULL)); ++ BN_CTX_free(ctx); + return 1; + } + +@@ -450,7 +475,6 @@ static const luaL_Reg R[] = + + int luaopen_bn(lua_State *L) + { +- ctx = BN_CTX_new(); + ERR_load_BN_strings(); + RAND_seed(MYVERSION, sizeof(MYVERSION)); + +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/lhash.c luvi-src-v2.7.6/deps/lua-openssl/src/lhash.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/lhash.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/lhash.c 2019-02-13 11:53:24.275126573 +0100 +@@ -8,6 +8,7 @@ + #include "private.h" + #include + ++#if 0 + static void table2data(lua_State*L, int idx, BIO* bio) + { + lua_pushnil(L); +@@ -27,6 +28,7 @@ static void table2data(lua_State*L, int + lua_pop(L, 1); + } + } ++#endif + + static LUA_FUNCTION(openssl_lhash_read) + { +@@ -44,7 +46,6 @@ static LUA_FUNCTION(openssl_lhash_read) + lua_pushfstring(L, "ERROR at LINE %d", eline); + return luaL_argerror(L, 1, lua_tostring(L, -1)); + } +- return 0; + } + + +@@ -128,19 +129,25 @@ static void dump_value_doall_arg(CONF_VA + } + } + } +-#if OPENSSL_VERSION_NUMBER >= 0x10000002L ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && defined(LIBRESSL_VERSION_NUMBER)==0 ++IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, lua_State); ++#elif OPENSSL_VERSION_NUMBER >= 0x10000002L + static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, lua_State) + #endif ++#if defined(LIBRESSL_VERSION_NUMBER)==0 + #define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ + lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) +- ++#endif + + static LUA_FUNCTION(openssl_lhash_parse) + { + LHASH* lhash = CHECK_OBJECT(1, LHASH, "openssl.lhash"); + + lua_newtable(L); +-#if OPENSSL_VERSION_NUMBER >= 0x10000002L ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && defined(LIBRESSL_VERSION_NUMBER)==0 ++ lh_CONF_VALUE_doall_lua_State(lhash, dump_value_doall_arg, L); ++#elif OPENSSL_VERSION_NUMBER >= 0x10000002L + lh_CONF_VALUE_doall_arg(lhash, LHASH_DOALL_ARG_FN(dump_value), lua_State, L); + #else + lh_doall_arg(lhash, (LHASH_DOALL_ARG_FN_TYPE)dump_value_doall_arg, L); +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/misc.c luvi-src-v2.7.6/deps/lua-openssl/src/misc.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/misc.c 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/misc.c 2019-02-13 11:53:24.275126573 +0100 +@@ -25,10 +25,10 @@ BIO* load_bio_object(lua_State* L, int i + /* read only */ + bio = (BIO*)BIO_new_mem_buf((void*)ctx, l); + } +- else if (auxiliar_isclass(L, "openssl.bio", idx)) ++ else if (auxiliar_getclassudata(L, "openssl.bio", idx)) + { + bio = CHECK_OBJECT(idx, BIO, "openssl.bio"); +- CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); ++ BIO_up_ref(bio); + } + else + luaL_argerror(L, idx, "only support string or openssl.bio"); +@@ -39,29 +39,40 @@ int bio_is_der(BIO* bio) + { + byte head[1]; + int len = BIO_read(bio, head, sizeof(head)); +- BIO_reset(bio); ++ (void)BIO_reset(bio); + if (len == sizeof(head) && head[0] == 0x30) +- { + return 1; +- } + + return 0; + } + +-const EVP_MD* get_digest(lua_State* L, int idx) ++const EVP_MD* get_digest(lua_State* L, int idx, const char* def_alg) + { + const EVP_MD* md = NULL; +- if (lua_isstring(L, idx)) ++ switch (lua_type(L, idx)) ++ { ++ case LUA_TSTRING: + md = EVP_get_digestbyname(lua_tostring(L, idx)); +- else if (lua_isnumber(L, idx)) ++ break; ++ case LUA_TNUMBER: + md = EVP_get_digestbynid(lua_tointeger(L, idx)); +- else if (auxiliar_isclass(L, "openssl.asn1_object", idx)) +- md = EVP_get_digestbyobj(CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object")); +- else if (auxiliar_isclass(L, "openssl.evp_digest", idx)) +- md = CHECK_OBJECT(idx, EVP_MD, "openssl.evp_digest"); +- else ++ break; ++ case LUA_TUSERDATA: ++ if (auxiliar_getclassudata(L, "openssl.asn1_object", idx)) ++ md = EVP_get_digestbyobj(CHECK_OBJECT(idx, ASN1_OBJECT, "openssl.asn1_object")); ++ else if (auxiliar_getclassudata(L, "openssl.evp_digest", idx)) ++ md = CHECK_OBJECT(idx, EVP_MD, "openssl.evp_digest"); ++ break; ++ case LUA_TNONE: ++ case LUA_TNIL: ++ if (def_alg != NULL) ++ md = EVP_get_digestbyname(def_alg); ++ break; ++ } ++ ++ if (md==NULL) + { +- luaL_error(L, "argument #1 must be a string, NID number or asn1_object identity digest method"); ++ luaL_argerror(L, idx, "must be a string, NID number or asn1_object identity digest method"); + } + + return md; +@@ -70,20 +81,30 @@ const EVP_MD* get_digest(lua_State* L, i + const EVP_CIPHER* get_cipher(lua_State*L, int idx, const char* def_alg) + { + const EVP_CIPHER* cipher = NULL; +- if (lua_isstring(L, idx)) ++ ++ switch (lua_type(L, idx)) ++ { ++ case LUA_TSTRING: + cipher = EVP_get_cipherbyname(lua_tostring(L, idx)); +- else if (lua_isnumber(L, idx)) ++ break; ++ case LUA_TNUMBER: + cipher = EVP_get_cipherbynid(lua_tointeger(L, idx)); +- else if (auxiliar_isclass(L, "openssl.asn1_object", idx)) +- cipher = EVP_get_cipherbyobj(CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object")); +- else if (auxiliar_isclass(L, "openssl.evp_cipher", idx)) +- cipher = CHECK_OBJECT(idx, EVP_CIPHER, "openssl.evp_cipher"); +- else if (lua_isnoneornil(L, idx) && def_alg) +- cipher = EVP_get_cipherbyname(def_alg); +- else ++ break; ++ case LUA_TUSERDATA: ++ if (auxiliar_getclassudata(L, "openssl.asn1_object", idx)) ++ cipher = EVP_get_cipherbyobj(CHECK_OBJECT(idx, ASN1_OBJECT, "openssl.asn1_object")); ++ else if (auxiliar_getclassudata(L, "openssl.evp_cipher", idx)) ++ cipher = CHECK_OBJECT(idx, EVP_CIPHER, "openssl.evp_cipher"); ++ break; ++ case LUA_TNONE: ++ case LUA_TNIL: ++ if (def_alg != NULL) ++ cipher = EVP_get_cipherbyname(def_alg); ++ break; ++ } ++ ++ if (cipher==NULL) + luaL_argerror(L, idx, "must be a string, NID number or asn1_object identity cipher method"); +- if (cipher == NULL) +- luaL_argerror(L, idx, "not valid cipher alg"); + + return cipher; + } +@@ -105,6 +126,11 @@ BIGNUM *BN_get(lua_State *L, int i) + } + case LUA_TUSERDATA: + BN_copy(x, CHECK_OBJECT(i, BIGNUM, "openssl.bn")); ++ break; ++ case LUA_TNIL: ++ BN_free(x); ++ x = NULL; ++ break; + } + return x; + } +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/ocsp.c luvi-src-v2.7.6/deps/lua-openssl/src/ocsp.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/ocsp.c 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/ocsp.c 2019-02-13 11:53:24.275126573 +0100 +@@ -36,7 +36,7 @@ static int openssl_ocsp_request_new(lua_ + ASN1_BIT_STRING *ikey = X509_get0_pubkey_bitstr(issuer); + + OCSP_CERTID *id = NULL; +- OCSP_ONEREQ *one; ++ OCSP_ONEREQ *one = NULL; + char buf[1024]; + int nonce = lua_gettop(L) > 2 ? auxiliar_checkboolean(L, 3) : 0; + req = OCSP_REQUEST_new(); +@@ -48,7 +48,7 @@ static int openssl_ocsp_request_new(lua_ + for (i = 1; i <= len; i++) + { + lua_rawgeti(L, 2, i); +- if (auxiliar_isclass(L, "openssl.x509", -1)) ++ if (auxiliar_getclassudata(L, "openssl.x509", -1)) + { + X509 *cert = CHECK_OBJECT(2, X509, "openssl.x509"); + id = OCSP_cert_to_id(NULL, cert, issuer); +@@ -65,18 +65,32 @@ static int openssl_ocsp_request_new(lua_ + { + id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno); + one = OCSP_request_add0_id(req, id); +- }; ++ } + ASN1_INTEGER_free(sno); + BIO_free(bio); + } ++ if (!one) ++ { ++ OCSP_CERTID_free(id); ++ OCSP_REQUEST_free(req); ++ req = NULL; ++ lua_pop(L, 1); ++ break; ++ } + lua_pop(L, 1); + } + } +- else if (auxiliar_isclass(L, "openssl.x509", 2)) ++ else if (auxiliar_getclassudata(L, "openssl.x509", 2)) + { + X509 *cert = CHECK_OBJECT(2, X509, "openssl.x509"); + id = OCSP_cert_to_id(NULL, cert, issuer); + one = OCSP_request_add0_id(req, id); ++ if (!one) ++ { ++ OCSP_CERTID_free(id); ++ OCSP_REQUEST_free(req); ++ req = NULL; ++ } + } + else + { +@@ -87,7 +101,13 @@ static int openssl_ocsp_request_new(lua_ + { + id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno); + one = OCSP_request_add0_id(req, id); +- }; ++ if (!one) ++ { ++ OCSP_CERTID_free(id); ++ OCSP_REQUEST_free(req); ++ req = NULL; ++ } ++ } + ASN1_INTEGER_free(sno); + BIO_free(bio); + } +@@ -108,15 +128,12 @@ static int openssl_ocsp_request_new(lua_ + static int openssl_ocsp_request_export(lua_State*L) + { + OCSP_REQUEST *req = CHECK_OBJECT(1, OCSP_REQUEST, "openssl.ocsp_request"); +- int pem = 1; ++ int pem = lua_gettop(L) > 1 ? auxiliar_checkboolean(L, 2) : 0; + int ret = 0; + BIO* bio; + BUF_MEM *buf; +- if (lua_gettop(L) > 1) +- pem = auxiliar_checkboolean(L, 2); + + bio = BIO_new(BIO_s_mem()); +- /* + if (pem) + { + ret = PEM_write_bio_OCSP_REQUEST(bio, req); +@@ -125,8 +142,6 @@ static int openssl_ocsp_request_export(l + { + ret = i2d_OCSP_REQUEST_bio(bio, req); + } +- */ +- ret = i2d_OCSP_REQUEST_bio(bio, req); + if (ret) + { + BIO_get_mem_ptr(bio, &buf); +@@ -153,8 +168,6 @@ static int openssl_ocsp_request_sign(lua + int ret; + int sflags = 0; + +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 3, "must be private key"); +- + if (lua_isnoneornil(L, 4)) + { + sflags = OCSP_NOCERTS; +@@ -172,16 +185,47 @@ static int openssl_ocsp_request_sign(lua + return 1; + } + ++static int openssl_push_ocsp_certid(lua_State*L, OCSP_CERTID* cid) ++{ ++ ASN1_OCTET_STRING *iNameHash = NULL; ++ ASN1_OBJECT *md = NULL; ++ ASN1_OCTET_STRING *ikeyHash = NULL; ++ ASN1_INTEGER *serial = NULL; ++ ++ int ret = OCSP_id_get0_info(&iNameHash, &md, &ikeyHash, &serial, cid); ++ if (ret == 1) ++ { ++ lua_newtable(L); ++ ++ PUSH_ASN1_OCTET_STRING(L, iNameHash); ++ lua_setfield(L, -2, "issuerNameHash"); ++ ++ PUSH_ASN1_OCTET_STRING(L, ikeyHash); ++ lua_setfield(L, -2, "issuerKeyHash"); ++ ++ PUSH_ASN1_INTEGER(L, serial); ++ lua_setfield(L, -2, "serialNumber"); ++ ++ PUSH_OBJECT(md, "openssl.asn1_object"); ++ lua_setfield(L, -2, "hashAlgorithm"); ++ } ++ else ++ lua_pushnil(L); ++ return 1; ++} + + static int openssl_ocsp_request_parse(lua_State*L) + { + OCSP_REQUEST *req = CHECK_OBJECT(1, OCSP_REQUEST, "openssl.ocsp_request"); ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + OCSP_REQINFO *inf = req->tbsRequest; + OCSP_SIGNATURE *sig = req->optionalSignature; +- ++#endif + BIO* bio = BIO_new(BIO_s_mem()); + int i, num; + lua_newtable(L); ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + AUXILIAR_SET(L, -1, "version", ASN1_INTEGER_get(inf->version), integer); + if (inf->requestorName) + { +@@ -189,39 +233,33 @@ static int openssl_ocsp_request_parse(lu + lua_setfield(L, -2, "requestorName"); + } + num = sk_OCSP_ONEREQ_num(inf->requestList); ++#endif ++ ++ num = OCSP_request_onereq_count(req); + lua_newtable(L); + for (i = 0; i < num; i++) + { +- OCSP_ONEREQ *one = sk_OCSP_ONEREQ_value(inf->requestList, i); +- OCSP_CERTID *a = one->reqCert; +- lua_newtable(L); +- { +- openssl_push_x509_algor(L, a->hashAlgorithm); +- lua_setfield(L, -2, "hashAlgorithm"); +- +- PUSH_ASN1_OCTET_STRING(L, a->issuerNameHash); +- lua_setfield(L, -2, "issuerNameHash"); +- +- PUSH_ASN1_OCTET_STRING(L, a->issuerKeyHash); +- lua_setfield(L, -2, "issuerKeyHash"); +- +- PUSH_ASN1_INTEGER(L, a->serialNumber); +- lua_setfield(L, -2, "serialNumber"); +- } ++ OCSP_ONEREQ *one = OCSP_request_onereq_get0(req, i); ++ OCSP_CERTID *cid = OCSP_onereq_get0_id(one); ++ openssl_push_ocsp_certid(L, cid); + lua_rawseti(L, -2, i + 1); + } + lua_setfield(L, -2, "requestList"); + +- if (inf->requestExtensions) ++ num = OCSP_REQUEST_get_ext_count(req); ++ lua_newtable(L); ++ for (i = 0; i < num; i++) + { +- lua_pushstring(L, "extensions"); +- openssl_sk_x509_extension_totable(L, inf->requestExtensions); +- lua_rawset(L, -3); ++ X509_EXTENSION* e = OCSP_REQUEST_get_ext(req, i); ++ PUSH_OBJECT(e, "openssl.x509_extension"); ++ lua_rawseti(L, -2, i + 1); + } ++ lua_setfield(L, -2, "extensions"); + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + if (sig) + { +- BIO_reset(bio); ++ (void)BIO_reset(bio); + X509_signature_print(bio, sig->signatureAlgorithm, sig->signature); + for (i = 0; i < sk_X509_num(sig->certs); i++) + { +@@ -229,7 +267,7 @@ static int openssl_ocsp_request_parse(lu + PEM_write_bio_X509(bio, sk_X509_value(sig->certs, i)); + } + } +- ++#endif + BIO_free(bio); + return 1; + } +@@ -268,7 +306,6 @@ static int openssl_ocsp_response(lua_Sta + + int i, id_count, type; + BIO* bio = NULL; +- luaL_argcheck(L, openssl_pkey_is_private(rkey), 4, "must be private key"); + + type = lua_type(L, 5); + if (type != LUA_TFUNCTION && type != LUA_TTABLE) +@@ -305,7 +342,7 @@ static int openssl_ocsp_response(lua_Sta + if (lua_istable(L, 5)) + { + BUF_MEM *buf; +- BIO_reset(bio); ++ (void)BIO_reset(bio); + i2a_ASN1_INTEGER(bio, serial); + + BIO_get_mem_ptr(bio, &buf); +@@ -406,15 +443,12 @@ static int openssl_ocsp_response(lua_Sta + static int openssl_ocsp_response_export(lua_State*L) + { + OCSP_RESPONSE *res = CHECK_OBJECT(1, OCSP_RESPONSE, "openssl.ocsp_response"); +- int pem = 1; ++ int pem = lua_gettop(L) > 1 ? auxiliar_checkboolean(L, 2) : 0; + int ret = 0; + BIO* bio; + BUF_MEM *buf; +- if (lua_gettop(L) > 1) +- pem = auxiliar_checkboolean(L, 2); + + bio = BIO_new(BIO_s_mem()); +- /* + if (pem) + { + ret = PEM_write_bio_OCSP_RESPONSE(bio, res); +@@ -423,8 +457,6 @@ static int openssl_ocsp_response_export( + { + ret = i2d_OCSP_RESPONSE_bio(bio, res); + } +- */ +- ret = i2d_OCSP_RESPONSE_bio(bio, res); + if (ret) + { + BIO_get_mem_ptr(bio, &buf); +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/openssl.c luvi-src-v2.7.6/deps/lua-openssl/src/openssl.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/openssl.c 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/openssl.c 2019-02-13 11:53:24.275126573 +0100 +@@ -1,10 +1,11 @@ +-/*=========================================================================*\ +-* openssl.c +-* lua-openssl binding +-* +-* This product includes PHP software, freely available from +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++lua-openssl binding, provide openssl base function in lua. ++ ++@module openssl ++@usage ++ openssl = require('openssl') ++*/ ++ + #include "openssl.h" + #include + #include +@@ -12,6 +13,12 @@ + #include + #include "private.h" + ++/*** ++get lua-openssl version ++@function version ++@tparam[opt] boolean format result will be number when set true, or string ++@treturn lua-openssl version, lua version, openssl version ++*/ + static int openssl_version(lua_State*L) + { + int num = lua_isnoneornil(L, 1) ? 0 : auxiliar_checkboolean(L, 1); +@@ -20,7 +27,6 @@ static int openssl_version(lua_State*L) + lua_pushinteger(L, LOPENSSL_VERSION_NUM); + lua_pushinteger(L, LUA_VERSION_NUM); + lua_pushinteger(L, OPENSSL_VERSION_NUMBER); +- + } + else + { +@@ -31,6 +37,13 @@ static int openssl_version(lua_State*L) + return 3; + } + ++/*** ++hex encode or decode string ++@function hex ++@tparam string str ++@tparam[opt=true] boolean encode true to encoed, false to decode ++@treturn string ++*/ + static LUA_FUNCTION(openssl_hex) + { + size_t l = 0; +@@ -59,6 +72,14 @@ static LUA_FUNCTION(openssl_hex) + return 1; + } + ++/*** ++base64 encode or decode ++@function base64 ++@tparam string|bio input ++@tparam[opt=true] boolean encode true to encoed, false to decode ++@tparam[opt=true] boolean NO_NL true with newline, false without newline ++@treturn string ++*/ + static LUA_FUNCTION(openssl_base64) + { + BIO *inp = load_bio_object(L, 1); +@@ -75,7 +96,7 @@ static LUA_FUNCTION(openssl_base64) + BIO_push(b64, out); + BIO_get_mem_ptr(inp, &mem); + BIO_write(b64, mem->data, mem->length); +- BIO_flush(b64); ++ (void)BIO_flush(b64); + } + else + { +@@ -84,7 +105,7 @@ static LUA_FUNCTION(openssl_base64) + BIO_push(b64, inp); + while ((inlen = BIO_read(b64, inbuf, 512)) > 0) + BIO_write(out, inbuf, inlen); +- BIO_flush(out); ++ (void)BIO_flush(out); + } + + BIO_get_mem_ptr(out, &mem); +@@ -108,6 +129,12 @@ static void list_callback(const OBJ_NAME + lua_rawseti(L, -2, idx + 1); + } + ++/*** ++get method names ++@function list ++@tparam string type support 'cipher','digests','pkeys','comps' ++@treturn table as array ++*/ + static LUA_FUNCTION(openssl_list) + { + static int options[] = +@@ -124,6 +151,22 @@ static LUA_FUNCTION(openssl_list) + return 1; + } + ++/*** ++get last or given error infomation ++ ++Most lua-openssl function or methods return nil or false when error or ++failed, followed by string type error _reason_ and number type error _code_, ++_code_ can pass to openssl.error() to get more error information. ++ ++@function error ++@tparam[opt] number error, default use ERR_get_error() return value ++@tparam[opt=false] boolean clear the current thread's error queue. ++@treturn number errcode ++@treturn string reason ++@treturn string library name ++@treturn string function name ++@treturn boolean is this is fatal error ++*/ + static LUA_FUNCTION(openssl_error_string) + { + unsigned long val; +@@ -159,13 +202,21 @@ static LUA_FUNCTION(openssl_error_string + return ret; + } + ++/*** ++load rand seed from file ++@function rand_load ++@tparam[opt=nil] string file path to laod seed, default opensl management ++@treturn boolean result ++*/ + static int openssl_random_load(lua_State*L) + { + const char *file = luaL_optstring(L, 1, NULL); + char buffer[MAX_PATH]; ++ int len; + + if (file == NULL) + file = RAND_file_name(buffer, sizeof buffer); ++#ifndef OPENSSL_NO_EGD + else if (RAND_egd(file) > 0) + { + /* we try if the given filename is an EGD socket. +@@ -173,8 +224,9 @@ static int openssl_random_load(lua_State + lua_pushboolean(L, 1); + return 1; + } +- +- if (file == NULL || !RAND_load_file(file, 2048)) ++#endif ++ len = luaL_optinteger(L, 2, 2048); ++ if (file == NULL || !RAND_load_file(file, len)) + { + return openssl_pushresult(L, 0); + } +@@ -183,25 +235,39 @@ static int openssl_random_load(lua_State + return 1; + } + ++/*** ++save rand seed to file ++@function rand_write ++@tparam[opt=nil] string file path to save seed, default openssl management ++@treturn bool result ++*/ + static int openssl_random_write(lua_State *L) + { + const char *file = luaL_optstring(L, 1, NULL); + char buffer[MAX_PATH]; +- int n; + +- if (!file && !(file = RAND_file_name(buffer, sizeof buffer))) ++ if (file == NULL && (file = RAND_file_name(buffer, sizeof buffer)) == NULL) + return openssl_pushresult(L, 0); + +- n = RAND_write_file(file); ++ RAND_write_file(file); + return openssl_pushresult(L, 1); + } + ++/*** ++get random generator state ++@function rand_status ++@tparam boolean result true for sucess ++*/ + static int openssl_random_status(lua_State *L) + { + lua_pushboolean(L, RAND_status()); + return 1; + } + ++/*** ++cleanup random genrator ++@function rand_cleanup ++*/ + static int openssl_random_cleanup(lua_State *L) + { + (void) L; +@@ -209,6 +275,13 @@ static int openssl_random_cleanup(lua_St + return 0; + } + ++/*** ++get random bytes ++@function random ++@tparam number length ++@tparam[opt=false] boolean strong true to generate strong randome bytes ++@treturn string ++*/ + static LUA_FUNCTION(openssl_random_bytes) + { + long length = luaL_checkint(L, 1); +@@ -251,6 +324,42 @@ static LUA_FUNCTION(openssl_random_bytes + return 1; + } + ++/*** ++set FIPS mode ++@function FIPS_mode ++@tparam boolean fips true enable FIPS mode, false disable it. ++@treturn boolean success ++*/ ++ ++/*** ++get FIPS mode ++@function FIPS_mode ++@treturn boolean return true when FIPS mode enabled, false when FIPS mode disabled. ++*/ ++static int openssl_fips_mode(lua_State *L) ++{ ++#if defined(LIBRESSL_VERSION_NUMBER) ++ return 0; ++#else ++ int ret =0, on = 0; ++ if(lua_isnone(L, 1)) ++ { ++ on = FIPS_mode(); ++ lua_pushboolean(L, on); ++ return 1; ++ } ++ ++ on = auxiliar_checkboolean(L, 1); ++ ret = FIPS_mode_set(on); ++ if(ret) ++ lua_pushboolean(L, ret); ++ else ++ ret = openssl_pushresult(L, ret); ++ return ret; ++#endif ++} ++ ++#ifndef OPENSSL_NO_CRYPTO_MDEBUG + static int openssl_mem_leaks(lua_State*L) + { + BIO *bio = BIO_new(BIO_s_mem()); +@@ -263,15 +372,23 @@ static int openssl_mem_leaks(lua_State*L + BIO_free(bio); + return 1; + } ++#endif + ++/*** ++get openssl engine object ++@function engine ++@tparam string engine_id ++@treturn engine ++*/ + static const luaL_Reg eay_functions[] = + { + {"version", openssl_version}, + {"list", openssl_list}, + {"hex", openssl_hex}, + {"base64", openssl_base64}, ++#ifndef OPENSSL_NO_CRYPTO_MDEBUG + {"mem_leaks", openssl_mem_leaks}, +- ++#endif + {"rand_status", openssl_random_status}, + {"rand_load", openssl_random_load}, + {"rand_write", openssl_random_write}, +@@ -280,6 +397,7 @@ static const luaL_Reg eay_functions[] = + + {"error", openssl_error_string}, + {"engine", openssl_engine}, ++ {"FIPS_mode", openssl_fips_mode}, + + {NULL, NULL} + }; +@@ -289,10 +407,46 @@ void CRYPTO_thread_setup(void); + void CRYPTO_thread_cleanup(void); + #endif + ++static int luaclose_openssl(lua_State *L) ++{ ++#if !defined(LIBRESSL_VERSION_NUMBER) ++ FIPS_mode_set(0); ++#endif ++#if defined(OPENSSL_THREADS) ++ CRYPTO_thread_cleanup(); ++#endif ++ CRYPTO_set_locking_callback(NULL); ++ CRYPTO_set_id_callback(NULL); ++ ++ ENGINE_cleanup(); ++ CONF_modules_unload(1); ++ ++ ERR_free_strings(); ++ EVP_cleanup(); ++ ++ CRYPTO_cleanup_all_ex_data(); ++#ifndef OPENSSL_NO_CRYPTO_MDEBUG ++#if !(defined(OPENSSL_NO_STDIO) || defined(OPENSSL_NO_FP_API)) ++#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L ++ CRYPTO_mem_leaks_fp(stderr); ++#else ++ if(CRYPTO_mem_leaks_fp(stderr)!=1) ++ { ++ fprintf(stderr, ++ "Please report a bug on https://github.com/zhaozg/lua-openssl." ++ "And if can, please provide a reproduce method and minimal code.\n" ++ "\n\tThank You."); ++ } ++#endif ++#endif /* OPENSSL_NO_STDIO or OPENSSL_NO_FP_API */ ++#endif /* OPENSSL_NO_CRYPTO_MDEBUG */ ++ return 0; ++} ++ + LUALIB_API int luaopen_openssl(lua_State*L) + { +- static int init = 0; +- if (init == 0) ++ static void* init = NULL; ++ if (init == NULL) + { + #if defined(OPENSSL_THREADS) + CRYPTO_thread_setup(); +@@ -309,15 +463,26 @@ LUALIB_API int luaopen_openssl(lua_State + ENGINE_load_dynamic(); + ENGINE_load_openssl(); + #ifdef LOAD_ENGINE_CUSTOM +- LOAD_ENGINE_CUSTOM(); ++ LOAD_ENGINE_CUSTOM + #endif + #ifdef OPENSSL_SYS_WINDOWS ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + RAND_screen(); + #endif +- init = 1; ++#endif + } + + lua_newtable(L); ++ if(init==NULL) ++ { ++ init = lua_newuserdata(L, sizeof(int)); ++ lua_newtable(L); ++ lua_pushcfunction(L, luaclose_openssl); ++ lua_setfield(L, -2, "__gc"); ++ lua_setmetatable(L, -2); ++ lua_setfield(L, -2, "__guard"); ++ } ++ + luaL_setfuncs(L, eay_functions, 0); + + openssl_register_lhash(L); +@@ -382,6 +547,11 @@ LUALIB_API int luaopen_openssl(lua_State + luaopen_dh(L); + lua_setfield(L, -2, "dh"); + ++#ifndef OPENSSL_NO_SRP ++ luaopen_srp(L); ++ lua_setfield(L, -2, "srp"); ++#endif ++ + #ifdef ENABLE_OPENSSL_GLOBAL + lua_pushvalue(L, -1); + lua_setglobal(L, "openssl"); +@@ -389,4 +559,3 @@ LUALIB_API int luaopen_openssl(lua_State + + return 1; + } +- +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/openssl.h luvi-src-v2.7.6/deps/lua-openssl/src/openssl.h +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/openssl.h 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/openssl.h 2019-02-13 11:53:24.275126573 +0100 +@@ -11,6 +11,7 @@ + #include + #include + #include "auxiliar.h" ++#include "subsidiar.h" + + #include + #include +@@ -26,7 +27,8 @@ + #include + #include + #include +- ++#include ++#include + + /*- + * Numeric release version identifier: +@@ -42,19 +44,16 @@ + * 0.9.3a 0x0090301f + * 0.9.4 0x0090400f + * 1.2.3z 0x102031af +-* +-* For continuity reasons (because 0.9.5 is already out, and is coded +-* 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level +-* part is slightly different, by setting the highest bit. This means +-* that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start +-* with 0x0090600S... +-* +-* (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) +-* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for +-* major minor fix final patch/beta) + */ +-#define LOPENSSL_VERSION_NUM 0x00500001 +-#define LOPENSSL_VERSION "0.5.1" ++ ++/*History ++ 2017-04-18 update to 0.7.1 ++ 2017-08-04 update to 0.7.3 ++*/ ++ ++/* MNNFFPPS */ ++#define LOPENSSL_VERSION_NUM 0x00703000 ++#define LOPENSSL_VERSION "0.7.3" + + #if OPENSSL_VERSION_NUMBER >= 0x10000000L + #include +@@ -78,14 +77,13 @@ __pragma(warning(pop)) + /* Common */ + #include + #ifndef MAX_PATH +-#define MAX_PATH PATH_MAX ++#define MAX_PATH 260 + #endif + + #ifdef NETWARE + #define timezone _timezone /* timezone is called _timezone in LibC */ + #endif + +- + #ifdef WIN32 + #define snprintf _snprintf + #ifndef strcasecmp +@@ -93,8 +91,13 @@ __pragma(warning(pop)) + #endif + #endif + +-#define LUA_FUNCTION(X) int X(lua_State *L) ++#ifdef _MSC_VER ++# ifndef inline ++# define inline __inline ++# endif ++#endif + ++#define LUA_FUNCTION(X) int X(lua_State *L) + + int openssl_s2i_revoke_reason(const char*s); + +@@ -127,6 +130,25 @@ void openssl_add_method(const OBJ_NAME * + #define CHECK_OBJECT(n,type,name) *(type**)auxiliar_checkclass(L,name,n) + #define CHECK_GROUP(n,type,name) *(type**)auxiliar_checkgroup(L,name,n) + ++static inline void* openssl_getclass(lua_State *L, const char* name, int idx) ++{ ++ void **p = (void**)auxiliar_getclassudata(L, name, idx); ++ if(p) ++ return *p; ++ return NULL; ++} ++ ++static inline void* openssl_getgroup(lua_State *L, const char* name, int idx) ++{ ++ void **p = (void**)auxiliar_getgroupudata(L, name, idx); ++ if(p) ++ return *p; ++ return NULL; ++} ++ ++#define GET_OBJECT(n,type,name) ((type*)openssl_getclass(L,name,n)) ++#define GET_GROUP(n,type,name) ((type*)openssl_getgroup(L,name,n)) ++ + #define PUSH_OBJECT(o, tname) \ + MULTI_LINE_MACRO_BEGIN \ + if(o) { \ +@@ -135,8 +157,11 @@ void openssl_add_method(const OBJ_NAME * + } else lua_pushnil(L); \ + MULTI_LINE_MACRO_END + ++#define FREE_OBJECT(i) (*(void**)lua_touserdata(L, i) = NULL) ++ + int openssl_register_lhash(lua_State* L); + int openssl_register_engine(lua_State* L); + +-#endif ++LUA_FUNCTION(luaopen_srp); + ++#endif +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/ots.c luvi-src-v2.7.6/deps/lua-openssl/src/ots.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/ots.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/ots.c 2019-02-13 11:53:24.298459641 +0100 +@@ -1,9 +1,10 @@ +-/*=========================================================================*\ +-* ots.c +-* timestamp module for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++timestamp module for lua-openssl binding ++create and manage x509 certificate sign request ++@module ts ++@usage ++ ts = require'openssl'.ts ++*/ + #include "openssl.h" + #include "private.h" + #include +@@ -14,6 +15,202 @@ + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + ++/*** ++create a new ts_req object. ++@function req_new ++@tparam[opt=1] integer version ++@treturn ts_req timestamp sign request object ++@see ts_req ++*/ ++static LUA_FUNCTION(openssl_ts_req_new) ++{ ++ TS_REQ *ts_req = TS_REQ_new(); ++ long version = luaL_optinteger(L, 1, 1); ++ ++ int ret = TS_REQ_set_version(ts_req, version); ++ if (ret == 1) ++ { ++ PUSH_OBJECT(ts_req, "openssl.ts_req"); ++ return 1; ++ } ++ TS_REQ_free(ts_req); ++ return 0; ++} ++ ++/*** ++read ts_req object from string or bio data ++@function req_read ++@tparam string|bio input ++@treturn ts_req timestamp sign request object ++@see ts_req ++*/ ++static LUA_FUNCTION(openssl_ts_req_read) ++{ ++ BIO *in = load_bio_object(L, 1); ++ TS_REQ *ts_req = d2i_TS_REQ_bio(in, NULL); ++ BIO_free(in); ++ if (ts_req) ++ { ++ PUSH_OBJECT(ts_req, "openssl.ts_req"); ++ return 1; ++ } ++ return 0; ++} ++ ++/*** ++read ts_resp object from string or bio input ++@function resp_read ++@tparam string|bio input ++@treturn ts_resp object ++*/ ++static LUA_FUNCTION(openssl_ts_resp_read) ++{ ++ BIO* in = load_bio_object(L, 1); ++ TS_RESP *res = d2i_TS_RESP_bio(in, NULL); ++ BIO_free(in); ++ if (res) ++ { ++ PUSH_OBJECT(res, "openssl.ts_resp"); ++ } ++ else ++ lua_pushnil(L); ++ return 1; ++} ++ ++/*** ++create ts_resp_ctx object ++@function resp_ctx_new ++@tparam[opt] x509 signer timestamp certificate ++@tparam[opt] evp_pkey pkey private key to sign ts_req ++@tparam[opt] asn1_object|string|nid identity for default policy object ++@treturn ts_resp_ctx object ++*/ ++static LUA_FUNCTION(openssl_ts_resp_ctx_new) ++{ ++ TS_RESP_CTX* ctx = TS_RESP_CTX_new(); ++ int i = 0; ++ int n = lua_gettop(L); ++ X509 *signer = NULL; ++ EVP_PKEY *pkey = NULL; ++ ASN1_OBJECT *obj = NULL; ++ int ret = 1; ++ ++ for (i = 1; i <= n; i++) ++ { ++ if (auxiliar_getclassudata(L, "openssl.x509", i)) ++ { ++ signer = CHECK_OBJECT(i, X509, "openssl.x509"); ++ } ++ else if (auxiliar_getclassudata(L, "openssl.evp_pkey", i)) ++ { ++ pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey"); ++ } ++ else if (auxiliar_getclassudata(L, "openssl.asn1_object", i)) ++ { ++ obj = CHECK_OBJECT(i, ASN1_OBJECT, "openssl.asn1_object"); ++ } ++ else if (lua_isnumber(L, i) || lua_isstring(L, i)) ++ { ++ int nid = openssl_get_nid(L, i); ++ luaL_argcheck(L, nid != NID_undef, i, "invalid asn1_object or object id"); ++ obj = OBJ_nid2obj(nid); ++ } ++ else ++ luaL_argerror(L, i, "not accept parameter"); ++ } ++ if (signer && pkey) ++ { ++ ret = X509_check_private_key(signer, pkey); ++ if (ret != 1) ++ { ++ luaL_error(L, "singer cert and private key not match"); ++ } ++ } ++ if (ret == 1 && obj != NULL) ++ ret = TS_RESP_CTX_set_def_policy(ctx, obj); ++ ++ if (ret == 1 && signer) ++ ret = TS_RESP_CTX_set_signer_cert(ctx, signer); ++ if (ret == 1 && pkey) ++ ret = TS_RESP_CTX_set_signer_key(ctx, pkey); ++ ++ if (ret == 1) ++ { ++ PUSH_OBJECT(ctx, "openssl.ts_resp_ctx"); ++ openssl_newvalue(L, ctx); ++ } ++ else ++ { ++ TS_RESP_CTX_free(ctx); ++ ctx = NULL; ++ lua_pushnil(L); ++ } ++ return 1; ++} ++ ++/*** ++create ts_verify_ctx object ++@function verify_ctx_new ++@tparam[opt=nil] string|ts_req reqdata ++@treturn ts_verify_ctx object ++*/ ++static LUA_FUNCTION(openssl_ts_verify_ctx_new) ++{ ++ TS_VERIFY_CTX *ctx = NULL; ++ if (lua_isnone(L, 1)) ++ { ++ ctx = TS_VERIFY_CTX_new(); ++ } ++ else if (lua_isstring(L, 1)) ++ { ++ BIO* bio = load_bio_object(L, 1); ++ TS_REQ* req = d2i_TS_REQ_bio(bio, NULL); ++ BIO_free(bio); ++ if (req) ++ { ++ ctx = TS_REQ_to_TS_VERIFY_CTX(req, NULL); ++ TS_REQ_free(req); ++ } ++ else ++ { ++ luaL_argerror(L, 1, "must be ts_req data or object or nil"); ++ } ++ } ++ else ++ { ++ TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); ++ ctx = TS_REQ_to_TS_VERIFY_CTX(req, NULL); ++ } ++ if (ctx) ++ { ++ PUSH_OBJECT(ctx, "openssl.ts_verify_ctx"); ++ } ++ else ++ lua_pushnil(L); ++ return 1; ++} ++ ++static luaL_Reg R[] = ++{ ++ {"req_new", openssl_ts_req_new}, ++ {"req_read", openssl_ts_req_read}, ++ {"resp_read", openssl_ts_resp_read}, ++ ++ {"resp_ctx_new", openssl_ts_resp_ctx_new }, ++ {"verify_ctx_new", openssl_ts_verify_ctx_new }, ++ ++ {NULL, NULL} ++}; ++ ++/*** ++openssl.ts_req object ++@type ts_req ++*/ ++/*** ++make a clone of ts_req object ++@function dup ++@treturn ts_req ++*/ + static int openssl_ts_req_dup(lua_State*L) + { + TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +@@ -22,6 +219,17 @@ static int openssl_ts_req_dup(lua_State* + return 1; + } + ++/*** ++get cert_req ++@function cert_req ++@treturn boolean true for set or not ++*/ ++/*** ++set cert_req ++@function cert_req ++@tparam boolean cert_req ++@treturn boolean result ++*/ + static int openssl_ts_req_cert_req(lua_State *L) + { + TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +@@ -38,6 +246,17 @@ static int openssl_ts_req_cert_req(lua_S + } + } + ++/*** ++get nonce ++@function nonce ++@treturn bn openssl.bn object ++*/ ++/*** ++set nonce ++@tparam string|bn nonce ++@treturn boolean result ++@function nonce ++*/ + static int openssl_ts_req_nonce(lua_State*L) + { + TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +@@ -61,6 +280,17 @@ static int openssl_ts_req_nonce(lua_Stat + } + } + ++/*** ++get policy_id ++@function policy_id ++@treturn asn1_object ++*/ ++/*** ++set policy_id ++@function policy_id ++@tparam asn1_object|number id identity for asn1_object ++@treturn boolean result ++*/ + static int openssl_ts_req_policy_id(lua_State*L) + { + TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +@@ -68,21 +298,39 @@ static int openssl_ts_req_policy_id(lua_ + { + ASN1_OBJECT* obj = TS_REQ_get_policy_id(req); + openssl_push_asn1object(L, obj); +- ASN1_OBJECT_free(obj); + return 1; + } + else + { +- int nid = openssl_get_nid(L, 2); +- ASN1_OBJECT* obj; ++ ASN1_OBJECT* obj = NULL; + int ret; +- luaL_argcheck(L, nid != NID_undef, 2, "must be asn1_object object identified"); +- obj = OBJ_nid2obj(nid); ++ if (auxiliar_getclassudata(L, "openssl.asn1_object", 2)) ++ { ++ obj = CHECK_OBJECT(2, ASN1_OBJECT, "openssl.asn1_object"); ++ } ++ else ++ { ++ int nid = openssl_get_nid(L, 2); ++ luaL_argcheck(L, nid != NID_undef, 2, "must be asn1_object object identified"); ++ obj = OBJ_nid2obj(nid); ++ } ++ + ret = TS_REQ_set_policy_id(req, obj); + return openssl_pushresult(L, ret); + } + } + ++/*** ++get version ++@treturn integer ++@function version ++*/ ++/*** ++set version ++@tparam integer version ++@treturn boolean result ++@function version ++*/ + static int openssl_ts_req_version(lua_State*L) + { + TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +@@ -99,6 +347,19 @@ static int openssl_ts_req_version(lua_St + } + } + ++/*** ++get msg_imprint ++@function msg_imprint ++@treturn string octet octet string ++@treturn table with algorithm and paramater ++*/ ++/*** ++set msg_imprint ++@function msg_imprint ++@tparam string data digest value of message ++@tparam[opt='sha'] string|evp_md md_alg ++@treturn boolean result ++*/ + static int openssl_ts_req_msg_imprint(lua_State*L) + { + TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +@@ -110,9 +371,8 @@ static int openssl_ts_req_msg_imprint(lu + ASN1_OCTET_STRING *s = TS_MSG_IMPRINT_get_msg(msg); + X509_ALGOR *a = TS_MSG_IMPRINT_get_algo(msg); + PUSH_ASN1_OCTET_STRING(L, s); +- openssl_push_x509_algor(L, a); +- ASN1_OCTET_STRING_free(s); +- X509_ALGOR_free(a); ++ a = X509_ALGOR_dup(a); ++ PUSH_OBJECT(a, "openssl.x509_algor"); + return 2; + } + return 1; +@@ -121,9 +381,7 @@ static int openssl_ts_req_msg_imprint(lu + { + size_t size; + const char* data = luaL_checklstring(L, 2, &size); +- const EVP_MD* md = lua_isnoneornil(L, 3) +- ? EVP_get_digestbyname("sha1") +- : get_digest(L, 3); ++ const EVP_MD* md = get_digest(L, 3, "sha256"); + TS_MSG_IMPRINT *msg = TS_MSG_IMPRINT_new(); + int ret = TS_MSG_IMPRINT_set_msg(msg, (unsigned char*)data, size); + if (ret == 1) +@@ -144,28 +402,11 @@ static int openssl_ts_req_msg_imprint(lu + } + }; + +-static LUA_FUNCTION(openssl_ts_req_new) +-{ +- TS_REQ *ts_req = TS_REQ_new(); +- long version = luaL_optinteger(L, 1, 1); +- +- int ret = TS_REQ_set_version(ts_req, version); +- if (ret == 1) +- { +- PUSH_OBJECT(ts_req, "openssl.ts_req"); +- return 1; +- } +- TS_REQ_free(ts_req); +- return 0; +-} +- +-static LUA_FUNCTION(openssl_ts_req_gc) +-{ +- TS_REQ *req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +- TS_REQ_free(req); +- return 0; +-} +- ++/*** ++create ts_verify_ctx from ts_req object ++@function to_verify_ctx ++@treturn ts_verify_ctx object ++*/ + static LUA_FUNCTION(openssl_ts_req_to_verify_ctx) + { + TS_REQ *req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +@@ -174,19 +415,11 @@ static LUA_FUNCTION(openssl_ts_req_to_ve + return 1; + } + +-static LUA_FUNCTION(openssl_ts_req_read) +-{ +- BIO *in = load_bio_object(L, 1); +- TS_REQ *ts_req = d2i_TS_REQ_bio(in, NULL); +- BIO_free(in); +- if (ts_req) +- { +- PUSH_OBJECT(ts_req, "openssl.ts_req"); +- return 1; +- } +- return 0; +-} +- ++/*** ++export ts_req to string ++@function export ++@treturn string ++*/ + static LUA_FUNCTION(openssl_ts_req_export) + { + TS_REQ *ts_req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +@@ -201,6 +434,11 @@ static LUA_FUNCTION(openssl_ts_req_expor + return 0; + } + ++/*** ++get info as table ++@function info ++@treturn table ++*/ + static LUA_FUNCTION(openssl_ts_req_info) + { + TS_REQ *req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +@@ -217,41 +455,52 @@ static LUA_FUNCTION(openssl_ts_req_info) + STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */ + } TS_REQ; + #endif +- PUSH_ASN1_INTEGER(L, req->version); ++ lua_pushinteger(L, TS_REQ_get_version(req)); + lua_setfield(L, -2, "version"); + +- AUXILIAR_SET(L, -1, "cert_req", req->cert_req, boolean); ++ AUXILIAR_SET(L, -1, "cert_req", TS_REQ_get_cert_req(req), boolean); + +- if (req->policy_id) ++ if (TS_REQ_get_policy_id(req)) + { +- openssl_push_asn1object(L, req->policy_id); ++ openssl_push_asn1object(L, TS_REQ_get_policy_id(req)); + lua_setfield(L, -2, "policy_id"); + } +- if (req->nonce) ++ if (TS_REQ_get_nonce(req)) + { +- PUSH_ASN1_INTEGER(L, req->nonce); ++ PUSH_ASN1_INTEGER(L, TS_REQ_get_nonce(req)); + lua_setfield(L, -2, "nonce"); + } + + lua_newtable(L); + { +- ASN1_OCTET_STRING *os = req->msg_imprint->hashed_msg; +- AUXILIAR_SETLSTR(L, -1, "content", (const char*)os->data, os->length); +- openssl_push_x509_algor(L, req->msg_imprint->hash_algo); ++ TS_MSG_IMPRINT *msg_inprint = TS_REQ_get_msg_imprint(req); ++ ASN1_OCTET_STRING *os = TS_MSG_IMPRINT_get_msg(msg_inprint); ++ X509_ALGOR *alg = TS_MSG_IMPRINT_get_algo(msg_inprint); ++ ++ AUXILIAR_SETLSTR(L, -1, "hashed_msg", (const char*)os->data, os->length); ++ alg = X509_ALGOR_dup(alg); ++ PUSH_OBJECT(alg, "openssl.x509_algor"); + lua_setfield(L, -2, "hash_algo"); + } + lua_setfield(L, -2, "msg_imprint"); + +- if (req->extensions) ++ if (TS_REQ_get_exts(req)) + { + lua_pushstring(L, "extensions"); +- openssl_sk_x509_extension_totable(L, req->extensions); ++ openssl_sk_x509_extension_totable(L, TS_REQ_get_exts(req)); + lua_rawset(L, -3); + } + + return 1; + } + ++static LUA_FUNCTION(openssl_ts_req_gc) ++{ ++ TS_REQ *req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); ++ TS_REQ_free(req); ++ return 0; ++} ++ + static luaL_Reg ts_req_funs[] = + { + {"dup", openssl_ts_req_dup}, +@@ -271,43 +520,10 @@ static luaL_Reg ts_req_funs[] = + { NULL, NULL } + }; + +-/***********************************************************/ +-static ASN1_INTEGER *tsa_serial_cb(TS_RESP_CTX *ctx, void *data) +-{ +- lua_State *L = (lua_State*) data; +- ASN1_INTEGER *serial = NULL; +- +- lua_rawgetp(L, LUA_REGISTRYINDEX, ctx); +- if (lua_isnil(L, -1)) +- { +- TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, +- "could not generate serial number"); +- +- return NULL; +- } +- +- if (lua_pcall(L, 0, 1, 0) == 0) +- { +- lua_Integer i = luaL_checkinteger(L, -1); +- serial = ASN1_INTEGER_new(); +- ASN1_INTEGER_set(serial, (long)i); +- return serial; +- } +- TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, +- "could not generate serial number"); +- +- return NULL; +- +- /* Acquire an exclusive lock for the serial file. */ +- /********************************************************* +- * Merge server id and serial number * +- * example : server_id = 0x0F , serial = 2 * +- * result = 0x0F2 * +- * Modification made by JOUVE * +- *********************************************************/ +-} +- +-/**************************************************************/ ++/*** ++openssl.ts_resp object ++@type ts_resp ++*/ + static LUA_FUNCTION(openssl_ts_resp_gc) + { + TS_RESP *res = CHECK_OBJECT(1, TS_RESP, "openssl.ts_resp"); +@@ -315,6 +531,11 @@ static LUA_FUNCTION(openssl_ts_resp_gc) + return 0; + } + ++/*** ++duplicate ts_resp object ++@function dup ++@treturn ts_resp object ++*/ + static LUA_FUNCTION(openssl_ts_resp_dup) + { + TS_RESP *res = CHECK_OBJECT(1, TS_RESP, "openssl.ts_resp"); +@@ -323,8 +544,14 @@ static LUA_FUNCTION(openssl_ts_resp_dup) + return 1; + } + ++/*** ++export ts_resp to string ++@function export ++@treturn string ++*/ + static LUA_FUNCTION(openssl_ts_resp_export) + { ++ int ret = 0; + TS_RESP *res = CHECK_OBJECT(1, TS_RESP, "openssl.ts_resp"); + BIO *bio = BIO_new(BIO_s_mem()); + if (i2d_TS_RESP_bio(bio, res)) +@@ -332,21 +559,42 @@ static LUA_FUNCTION(openssl_ts_resp_expo + BUF_MEM *bptr = NULL; + BIO_get_mem_ptr(bio, &bptr); + lua_pushlstring(L, bptr->data, bptr->length); +- BIO_free(bio); +- return 1; ++ ret = 1; + } +- return 0; ++ BIO_free(bio); ++ return ret; + } + +-static int openssl_push_ts_accuracy(lua_State*L, const TS_ACCURACY* accuracy) ++static int openssl_push_ts_accuracy(lua_State*L, const TS_ACCURACY* accuracy, int asobj) + { +- lua_newtable(L); +- PUSH_ASN1_INTEGER(L, accuracy->micros); +- lua_setfield(L, -2, "micros"); +- PUSH_ASN1_INTEGER(L, accuracy->millis); +- lua_setfield(L, -2, "millis"); +- PUSH_ASN1_INTEGER(L, accuracy->seconds); +- lua_setfield(L, -2, "seconds"); ++ if (accuracy) ++ { ++ if (asobj) ++ { ++ unsigned char *pbuf = NULL; ++ int len = i2d_TS_ACCURACY(accuracy, &pbuf); ++ if (len > 0) ++ { ++ lua_pushlstring(L, (const char*)pbuf, len); ++ OPENSSL_free(pbuf); ++ } ++ else ++ lua_pushnil(L); ++ } ++ else ++ { ++ lua_newtable(L); ++ ++ PUSH_ASN1_INTEGER(L, TS_ACCURACY_get_micros(accuracy)); ++ lua_setfield(L, -2, "micros"); ++ PUSH_ASN1_INTEGER(L, TS_ACCURACY_get_millis(accuracy)); ++ lua_setfield(L, -2, "millis"); ++ PUSH_ASN1_INTEGER(L, TS_ACCURACY_get_seconds(accuracy)); ++ lua_setfield(L, -2, "seconds"); ++ } ++ } ++ else ++ lua_pushnil(L); + + return 1; + } +@@ -358,7 +606,8 @@ static int openssl_push_ts_msg_imprint(l + lua_newtable(L); + if (alg) + { +- openssl_push_x509_algor(L, alg); ++ alg = X509_ALGOR_dup(alg); ++ PUSH_OBJECT(alg, "openssl.x509_algor"); + lua_setfield(L, -2, "algo"); + } + if (str) +@@ -373,62 +622,53 @@ static int openssl_push_ts_msg_imprint(l + static int openssl_push_ts_tst_info(lua_State*L, TS_TST_INFO* info) + { + lua_newtable(L); +- if (info->version) +- { +- PUSH_ASN1_INTEGER(L, info->version); +- lua_setfield(L, -2, "version"); +- } +- if (info->policy_id) +- { +- openssl_push_asn1object(L, info->policy_id); +- lua_setfield(L, -2, "policy_id"); +- } +- if (info->msg_imprint) +- { +- openssl_push_ts_msg_imprint(L, info->msg_imprint); +- lua_setfield(L, -2, "msg_imprint"); +- } +- if (info->serial) +- { +- PUSH_ASN1_INTEGER(L, info->serial); +- lua_setfield(L, -2, "serial"); +- } +- if (info->time) +- { +- openssl_push_asn1(L, info->time, V_ASN1_GENERALIZEDTIME); +- lua_setfield(L, -2, "time"); +- } +- if (info->accuracy) +- { +- openssl_push_ts_accuracy(L, info->accuracy); +- lua_setfield(L, -2, "accuracy"); +- } + +- AUXILIAR_SET(L, -1, "ordering", info->ordering, boolean); ++ lua_pushinteger(L, TS_TST_INFO_get_version(info)); ++ lua_setfield(L, -2, "version"); + +- if (info->nonce) +- { +- PUSH_ASN1_INTEGER(L, info->nonce); +- lua_setfield(L, -2, "nonce"); +- } +- if (info->tsa) +- { +- openssl_push_general_name(L, info->tsa); +- lua_setfield(L, -2, "tsa"); +- } +- if (info->extensions) ++ openssl_push_asn1object(L, TS_TST_INFO_get_policy_id(info)); ++ lua_setfield(L, -2, "policy_id"); ++ ++ openssl_push_ts_msg_imprint(L, TS_TST_INFO_get_msg_imprint(info)); ++ lua_setfield(L, -2, "msg_imprint"); ++ ++ PUSH_ASN1_INTEGER(L, TS_TST_INFO_get_serial(info)); ++ lua_setfield(L, -2, "serial"); ++ ++ openssl_push_asn1(L, TS_TST_INFO_get_time(info), V_ASN1_GENERALIZEDTIME); ++ lua_setfield(L, -2, "time"); ++ ++ openssl_push_ts_accuracy(L, TS_TST_INFO_get_accuracy(info), 1); ++ lua_setfield(L, -2, "accuracy"); ++ ++ AUXILIAR_SET(L, -1, "ordering", TS_TST_INFO_get_ordering(info), boolean); ++ ++ PUSH_ASN1_INTEGER(L, TS_TST_INFO_get_nonce(info)); ++ lua_setfield(L, -2, "nonce"); ++ ++ openssl_push_general_name(L, TS_TST_INFO_get_tsa(info)); ++ lua_setfield(L, -2, "tsa"); ++ ++ if (TS_TST_INFO_get_exts(info)) + { + lua_pushstring(L, "extensions"); +- openssl_sk_x509_extension_totable(L, info->extensions); ++ openssl_sk_x509_extension_totable(L, TS_TST_INFO_get_exts(info)); + lua_rawset(L, -3); + } ++ + return 1; + } + ++/*** ++get info as table ++@function tst_info ++@treturn table ++*/ + static LUA_FUNCTION(openssl_ts_resp_tst_info) + { + TS_RESP *resp = CHECK_OBJECT(1, TS_RESP, "openssl.ts_resp"); +- TS_TST_INFO *info = resp->tst_info; ++ TS_TST_INFO *info = TS_RESP_get_tst_info(resp); ++ + if (info) + openssl_push_ts_tst_info(L, info); + else +@@ -436,6 +676,11 @@ static LUA_FUNCTION(openssl_ts_resp_tst_ + return 1; + } + ++/*** ++get info as table ++@function info ++@treturn table ++*/ + static LUA_FUNCTION(openssl_ts_resp_info) + { + TS_RESP *res = CHECK_OBJECT(1, TS_RESP, "openssl.ts_resp"); +@@ -443,26 +688,28 @@ static LUA_FUNCTION(openssl_ts_resp_info + lua_newtable(L); + + { +- lua_newtable(L); ++ TS_STATUS_INFO *si = TS_RESP_get_status_info(res); ++ const ASN1_BIT_STRING *failure_info = TS_STATUS_INFO_get0_failure_info(si); + +- PUSH_ASN1_INTEGER(L, res->status_info->status); ++ lua_newtable(L); ++ PUSH_ASN1_INTEGER(L, TS_STATUS_INFO_get0_status(si)); + lua_setfield(L, -2, "status"); + +- if (res->status_info->failure_info) ++ if (failure_info) + { +- openssl_push_asn1(L, res->status_info->failure_info, V_ASN1_BIT_STRING); ++ openssl_push_asn1(L, failure_info, V_ASN1_BIT_STRING); + lua_setfield(L, -2, "failure_info"); + } + +- if (res->status_info->text) ++ if (TS_STATUS_INFO_get0_text(si)) + { +- STACK_OF(ASN1_UTF8STRING) * sk = res->status_info->text; ++ const STACK_OF(ASN1_UTF8STRING) * sk = TS_STATUS_INFO_get0_text(si); + int i = 0, n = 0; + lua_newtable(L); +- n = SKM_sk_num(ASN1_UTF8STRING, sk); ++ n = sk_ASN1_UTF8STRING_num(sk); + for (i = 0; i < n; i++) + { +- ASN1_UTF8STRING *x = SKM_sk_value(ASN1_UTF8STRING, sk, i); ++ ASN1_UTF8STRING *x = sk_ASN1_UTF8STRING_value(sk, i); + lua_pushlstring(L, (const char*)x->data, x->length); + lua_rawseti(L, -2, i + 1); + } +@@ -473,35 +720,21 @@ static LUA_FUNCTION(openssl_ts_resp_info + } + + +- if (res->token) ++ if (TS_RESP_get_token(res)) + { +- PKCS7* token = PKCS7_dup(res->token); ++ PKCS7* token = PKCS7_dup(TS_RESP_get_token(res)); + AUXILIAR_SETOBJECT(L, token, "openssl.pkcs7", -1, "token"); + } + +- if (res->tst_info) ++ if (TS_RESP_get_tst_info(res)) + { +- openssl_push_ts_tst_info(L, res->tst_info); ++ openssl_push_ts_tst_info(L, TS_RESP_get_tst_info(res)); + lua_setfield(L, -2, "tst_info"); + } + + return 1; + } + +-static LUA_FUNCTION(openssl_ts_resp_read) +-{ +- BIO* in = load_bio_object(L, 1); +- TS_RESP *res = d2i_TS_RESP_bio(in, NULL); +- BIO_free(in); +- if (res) +- { +- PUSH_OBJECT(res, "openssl.ts_resp"); +- } +- else +- lua_pushnil(L); +- return 1; +-} +- + static luaL_Reg ts_resp_funs[] = + { + {"dup", openssl_ts_resp_dup}, +@@ -516,7 +749,22 @@ static luaL_Reg ts_resp_funs[] = + }; + + /********************************************************/ +- ++/*** ++openssl.ts_resp_ctx object ++@type ts_resp_ctx ++*/ ++/*** ++create response for ts_req ++@function create_response ++@tparam string|bio|ts_req data support string,bio ts_req content or ts_req object ++@treturn ts_resp result ++*/ ++/*** ++sign ts_req and get ts_resp, alias of create_response ++@function sign ++@tparam string|bio|ts_req data support string,bio ts_req content or ts_req object ++@treturn ts_resp result ++*/ + static LUA_FUNCTION(openssl_ts_create_response) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +@@ -545,268 +793,189 @@ static LUA_FUNCTION(openssl_ts_create_re + return 1; + } + +-static LUA_FUNCTION(openssl_ts_resp_ctx_new) +-{ +- TS_RESP_CTX* ctx = TS_RESP_CTX_new(); +- int i = 0; +- int n = lua_gettop(L); +- X509 *signer = NULL; +- EVP_PKEY *pkey = NULL; +- int nid = NID_undef; +- int ret = 1; +- +- for (i = 1; i <= n; i++) +- { +- if (auxiliar_isclass(L, "openssl.x509", i)) +- { +- signer = CHECK_OBJECT(i, X509, "openssl.x509"); +- } +- else if (auxiliar_isclass(L, "openssl.evp_pkey", i)) +- { +- pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey"); +- luaL_argcheck(L, openssl_pkey_is_private(pkey), i, "must be private key"); +- } +- else if (lua_isnumber(L, i) || lua_isstring(L, i) || auxiliar_isclass(L, "openssl.asn1_object", i)) +- { +- nid = openssl_get_nid(L, i); +- luaL_argcheck(L, nid != NID_undef, i, "invalid asn1_object or object id"); +- } +- else +- luaL_argerror(L, i, "not accept paramater"); +- } +- if (signer && pkey) +- { +- ret = X509_check_private_key(signer, pkey); +- if (ret != 1) +- { +- luaL_error(L, "singer cert and private key not match"); +- } +- } +- if (ret == 1 && nid != NID_undef) +- ret = TS_RESP_CTX_set_def_policy(ctx, OBJ_nid2obj(nid)); +- +- if (ret == 1 && signer) +- ret = TS_RESP_CTX_set_signer_cert(ctx, signer); +- if (ret == 1 && pkey) +- ret = TS_RESP_CTX_set_signer_key(ctx, pkey); +- +- if (ret == 1) +- { +- PUSH_OBJECT(ctx, "openssl.ts_resp_ctx"); +- openssl_newvalue(L, ctx); +- } +- else +- { +- TS_RESP_CTX_free(ctx); +- ctx = NULL; +- lua_pushnil(L); +- } +- return 1; +-} +- ++/*** ++get signer cert and pkey ++@function signer ++@treturn x509 cert object or nil ++@treturn evp_pkey pkey object or nil ++*/ ++/*** ++set signer cert and pkey ++@function signer ++@tparam x509 cert signer cert ++@tparam evp_pkey pkey signer pkey ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_singer) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- if (lua_isnone(L, 2)) +- { +- if (ctx->signer_cert) +- { +- X509* x = ctx->signer_cert; +- x = X509_dup(x); +- PUSH_OBJECT(x, "openssl.x509"); +- } +- else +- lua_pushnil(L); +- if (ctx->signer_key) +- { +- EVP_PKEY* pkey = ctx->signer_key; +- CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); +- PUSH_OBJECT(pkey, "openssl.evp_pkey"); +- } +- else +- lua_pushnil(L); +- return 2; +- } +- else ++ X509 *signer = CHECK_OBJECT(2, X509, "openssl.x509"); ++ EVP_PKEY *pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); ++ int ret = X509_check_private_key(signer, pkey); ++ if (ret != 1) + { +- X509 *signer = CHECK_OBJECT(2, X509, "openssl.x509"); +- EVP_PKEY *pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); +- int ret; +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 3, "must be private key"); +- ret = X509_check_private_key(signer, pkey); +- if (ret != 1) +- { +- luaL_error(L, "signer cert and private key not match"); +- } +- if (ret == 1) +- ret = TS_RESP_CTX_set_signer_cert(ctx, signer); +- if (ret == 1) +- ret = TS_RESP_CTX_set_signer_key(ctx, pkey); +- return openssl_pushresult(L, ret); ++ luaL_error(L, "signer cert and private key not match"); + } ++ if (ret == 1) ++ ret = TS_RESP_CTX_set_signer_cert(ctx, signer); ++ if (ret == 1) ++ ret = TS_RESP_CTX_set_signer_key(ctx, pkey); ++ return openssl_pushresult(L, ret); + } + ++/*** ++set additional certs ++@function certs ++@tparam table certs array of certificates ++@treturn boolean success ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_certs) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- if (lua_isnone(L, 2)) +- { +- if (ctx->certs) +- { +- openssl_sk_x509_totable(L, ctx->certs); +- } +- else +- { +- lua_pushnil(L); +- }; +- } +- else +- { +- if (ctx->certs) +- { +- sk_X509_pop_free(ctx->certs, X509_free); +- } +- ctx->certs = openssl_sk_x509_fromtable(L, 2); +- lua_pushboolean(L, 1); +- } +- return 1; ++ STACK_OF(X509) *certs = openssl_sk_x509_fromtable(L, 2); ++ TS_RESP_CTX_set_certs(ctx, certs); ++ return 0; + } + ++/*** ++set default policy ++@function default_policy ++@tparam asn1_object|integer|string policy ++@treturn boolean success ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_default_policy) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- if (lua_isnone(L, 2)) +- { +- if (ctx->default_policy) +- openssl_push_asn1object(L, ctx->default_policy); +- else +- lua_pushnil(L); +- } +- else +- { +- int nid = openssl_get_nid(L, 2); +- if (ctx->default_policy) +- ASN1_OBJECT_free(ctx->default_policy); +- ctx->default_policy = OBJ_nid2obj(nid); +- lua_pushboolean(L, 1); +- } +- return 1; ++ int nid = openssl_get_nid(L, 2); ++ int ret = TS_RESP_CTX_set_def_policy(ctx, OBJ_nid2obj(nid)); ++ return openssl_pushresult(L, ret); + } + ++/*** ++set policies ++@function policies ++@tparam asn1_object|integer|string|stack_of_asn1_object|table policies ++@treturn boolean success ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_policies) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- if (lua_isnone(L, 2)) ++ ASN1_OBJECT *obj = NULL; ++ int ret = 1; ++ int nid; ++ int i; ++ int n = lua_gettop(L); ++ luaL_argcheck(L, n > 1, 2, "need one or more asn1_object"); ++ for (i = 2; i <= n && ret == 1; i++) + { +- if (ctx->policies) ++ if (lua_istable(L, i)) + { +- int i, n; +- lua_newtable(L); +- n = sk_ASN1_OBJECT_num(ctx->policies); +- for (i = 0; i < n; i++) ++ int j, k; ++ k = lua_rawlen(L, i); ++ for (j = 1; j <= k && ret == 1; j++) + { +- ASN1_OBJECT* obj = sk_ASN1_OBJECT_value(ctx->policies, i); +- lua_pushinteger(L, i + 1); +- PUSH_OBJECT(obj, "openssl.asn1_object"); +- lua_rawset(L, -3); +- } +- } +- else +- lua_pushnil(L); +- } +- else +- { +- if (lua_istable(L, 2)) +- { ++ lua_rawgeti(L, i, j); ++ if (auxiliar_getclassudata(L, "openssl.asn1_object", -1)) ++ { ++ obj = CHECK_OBJECT(-1, ASN1_OBJECT, "openssl.asn1_object"); ++ } ++ else ++ { ++ nid = openssl_get_nid(L, -1); ++ obj = nid!=NID_undef ? OBJ_nid2obj(nid) : NULL; ++ } + +- } +- else +- { +- int n = lua_gettop(L); +- int ret = 1; +- int nid; +- int i; +- for (i = 2; i <= n && ret == 1; i++) +- { +- if (lua_istable(L, i)) ++ lua_pop(L, 1); ++ ++ if (obj) + { +- int j, k; +- k = lua_rawlen(L, i); +- for (j = 1; j <= k && ret == 1; j++) +- { +- lua_rawgeti(L, i, j); +- nid = openssl_get_nid(L, -1); +- lua_pop(L, 1); +- +- if (nid != NID_undef) +- { +- ret = TS_RESP_CTX_add_policy(ctx, OBJ_nid2obj(nid)); +- } +- else +- { +- lua_pushfstring(L, "index %d is invalid asn1_object or object id", j); +- luaL_argerror(L, i, lua_tostring(L, -1)); +- } +- } ++ ret = TS_RESP_CTX_add_policy(ctx, obj); + } + else + { +- nid = openssl_get_nid(L, i); +- if (nid != NID_undef) +- { +- ret = TS_RESP_CTX_add_policy(ctx, OBJ_nid2obj(nid)); +- } +- else +- luaL_argerror(L, i, "invalid asn1_object or id"); ++ lua_pushfstring(L, "index %d is invalid asn1_object or object id", j); ++ luaL_argerror(L, i, lua_tostring(L, -1)); + } + } +- return openssl_pushresult(L, ret); ++ } ++ else ++ { ++ if (auxiliar_getclassudata(L, "openssl.asn1_object", i)) ++ { ++ obj = CHECK_OBJECT(i, ASN1_OBJECT, "openssl.asn1_object"); ++ } ++ else ++ { ++ nid = openssl_get_nid(L, i); ++ obj = nid != NID_undef ? OBJ_nid2obj(nid) : NULL; ++ } ++ if (obj) ++ { ++ ret = TS_RESP_CTX_add_policy(ctx, obj); ++ } ++ else ++ luaL_argerror(L, i, "invalid asn1_object or id"); + } + } +- return 1; ++ return openssl_pushresult(L, ret); + } + ++/*** ++get accuracy ++@function accuracy ++@treturn integer seconds ++@treturn integer millis ++@treturn integer micros ++*/ ++/*** ++set accuracy ++@function accuracy ++@tparam integer seconds ++@tparam integer millis ++@tparam integer micros ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_accuracy) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- if (lua_isnone(L, 2)) +- { +- lua_pushinteger(L, ASN1_INTEGER_get(ctx->seconds)); +- lua_pushinteger(L, ASN1_INTEGER_get(ctx->millis)); +- lua_pushinteger(L, ASN1_INTEGER_get(ctx->micros)); +- return 3; +- } +- else +- { +- int seconds = luaL_checkint(L, 2); +- int millis = luaL_checkint(L, 3); +- int micros = luaL_checkint(L, 4); +- int ret = TS_RESP_CTX_set_accuracy(ctx, seconds, millis, micros); +- return openssl_pushresult(L, ret); +- } ++ int seconds = luaL_checkint(L, 2); ++ int millis = luaL_checkint(L, 3); ++ int micros = luaL_checkint(L, 4); ++ int ret = TS_RESP_CTX_set_accuracy(ctx, seconds, millis, micros); ++ return openssl_pushresult(L, ret); + } + ++/*** ++get clock_precision_digits ++@function clock_precision_digits ++@treturn integer clock_precision_digits ++*/ ++/*** ++set clock_precision_digits ++@function clock_precision_digits ++@tparam integer clock_precision_digits ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_clock_precision_digits) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- if (lua_isnone(L, 2)) +- { +- lua_pushinteger(L, ctx->clock_precision_digits); +- return 1; +- } +- else +- { +- int ret; +- int clock_precision_digits = luaL_checkint(L, 2); +- if (clock_precision_digits > TS_MAX_CLOCK_PRECISION_DIGITS) +- clock_precision_digits = TS_MAX_CLOCK_PRECISION_DIGITS; +- if (clock_precision_digits < 0) +- clock_precision_digits = 0; +- ret = TS_RESP_CTX_set_clock_precision_digits(ctx, clock_precision_digits); +- return openssl_pushresult(L, ret); +- } ++ int ret; ++ int clock_precision_digits = luaL_checkint(L, 2); ++ if (clock_precision_digits > TS_MAX_CLOCK_PRECISION_DIGITS) ++ clock_precision_digits = TS_MAX_CLOCK_PRECISION_DIGITS; ++ if (clock_precision_digits < 0) ++ clock_precision_digits = 0; ++ ret = TS_RESP_CTX_set_clock_precision_digits(ctx, clock_precision_digits); ++ return openssl_pushresult(L, ret); + } + ++/*** ++set status info ++@function set_status_info ++@tparam integer status ++@tparam string text ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_set_status_info) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +@@ -816,6 +985,13 @@ static LUA_FUNCTION(openssl_ts_resp_ctx_ + return openssl_pushresult(L, ret); + } + ++/*** ++set status info cond ++@function set_status_info_cond ++@tparam integer status ++@tparam string text ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_set_status_info_cond) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +@@ -825,6 +1001,12 @@ static LUA_FUNCTION(openssl_ts_resp_ctx_ + return openssl_pushresult(L, ret); + } + ++/*** ++add failure info ++@function add_failure_info ++@tparam integer failure ++@treturn result ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_add_failure_info) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +@@ -833,51 +1015,35 @@ static LUA_FUNCTION(openssl_ts_resp_ctx_ + return openssl_pushresult(L, ret); + } + ++/*** ++get flags ++@function flags ++@treturn integer flags ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_flags) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- if (lua_isnone(L, 2)) +- { +- lua_pushinteger(L, ctx->flags); +- } +- else if (lua_isnumber(L, 2)) +- { +- int flags = luaL_checkint(L, 2); +- ctx->flags = flags; +- lua_pushboolean(L, 1); +- } +- else if (lua_isstring(L, 2)) +- { +- /* TS_RESP_CTX_add_flags(ctx, ) */ +- luaL_error(L, "not support"); +- } +- else +- luaL_error(L, "not support"); +- return 1; ++ int flags = luaL_checkint(L, 2); ++ TS_RESP_CTX_add_flags(ctx, flags); ++ return 0; + } + ++/*** ++set support digest method ++@function md ++@tparam table mds support digest method ++@treturn boolean result ++*/ ++/*** ++add digest ++@function md ++@tparam string|evp_digest md_alg ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_md) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- if (lua_isnone(L, 2)) +- { +- if (ctx->mds) +- { +- int i; +- int n = sk_EVP_MD_num(ctx->mds); +- lua_newtable(L); +- for (i = 0; i < n; i++) +- { +- EVP_MD* md = sk_EVP_MD_value(ctx->mds, i); +- PUSH_OBJECT(md, "openssl.evp_digest"); +- lua_rawseti(L, -2, i + 1); +- } +- } +- else +- lua_pushnil(L); +- return 1; +- } +- else if (lua_istable(L, 2)) ++ if (lua_istable(L, 2)) + { + int i; + int n = lua_rawlen(L, 2); +@@ -886,7 +1052,7 @@ static LUA_FUNCTION(openssl_ts_resp_ctx_ + { + const EVP_MD* md; + lua_rawgeti(L, 2, i); +- md = get_digest(L, -1); ++ md = get_digest(L, -1, NULL); + lua_pop(L, 1); + if (md) + { +@@ -903,12 +1069,17 @@ static LUA_FUNCTION(openssl_ts_resp_ctx_ + } + else + { +- const EVP_MD* md = get_digest(L, 2); ++ const EVP_MD* md = get_digest(L, 2, NULL); + int ret = TS_RESP_CTX_add_md(ctx, md); + return openssl_pushresult(L, ret); + } + } + ++/*** ++get tst_info as table ++@function tst_info ++@treturn table tst_info ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_tst_info) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +@@ -923,6 +1094,11 @@ static LUA_FUNCTION(openssl_ts_resp_ctx_ + return 1; + } + ++/*** ++get ts_req object ++@function request ++@treturn rs_req ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_request) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +@@ -938,9 +1114,7 @@ static LUA_FUNCTION(openssl_ts_resp_ctx_ + + typedef struct + { +- lua_State* L; + int callback; +- int ctx; + int cb_arg; + } TS_CB_ARG; + +@@ -949,112 +1123,186 @@ static const char* serial_cb_key = "seri + + static ASN1_INTEGER* openssl_serial_cb(TS_RESP_CTX*ctx, void*data) + { +- TS_CB_ARG *arg = (TS_CB_ARG*)data; +- lua_State* L = arg->L; +- ASN1_INTEGER *ai = NULL; + int err; +- (void)ctx; ++ TS_CB_ARG *arg; ++ lua_State* L = data; ++ ++ openssl_valueget(L, ctx, serial_cb_key); ++ if (!lua_isuserdata(L, -1)) ++ { ++ TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, ++ "Error during serial number generation."); ++ TS_RESP_CTX_add_failure_info(ctx, TS_INFO_ADD_INFO_NOT_AVAILABLE); ++ ++ lua_pop(L, 1); ++ return NULL; ++ } ++ arg = lua_touserdata(L, -1); ++ lua_pop(L, 1); /* remove openssl_valueget returned value */ ++ + lua_rawgeti(L, LUA_REGISTRYINDEX, arg->callback); +- lua_rawgeti(L, LUA_REGISTRYINDEX, arg->ctx); + lua_rawgeti(L, LUA_REGISTRYINDEX, arg->cb_arg); +- err = lua_pcall(L, 2, 1, 0); ++ err = lua_pcall(L, 1, 1, 0); + if (err == 0) + { ++ ASN1_INTEGER *ai = NULL; + BIGNUM *bn = BN_get(L, -1); +- lua_pop(L, 1); ++ lua_pop(L, 1); /* remove callback returned value */ + if (bn) + { + ai = BN_to_ASN1_INTEGER(bn, NULL); + BN_free(bn); + } + if (ai == NULL) +- luaL_error(L, "serial_cb not return openssl.bn"); ++ { ++ TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, ++ "Error during serial number generation."); ++ TS_RESP_CTX_add_failure_info(ctx, TS_INFO_ADD_INFO_NOT_AVAILABLE); ++ luaL_error(L, "Error during serial number generation."); ++ } ++ return ai; + } + else ++ { + lua_error(L); +- return ai; ++ } ++ return NULL; + }; + ++/*** ++set serial generate callback function ++@function set_serial_cb ++@tparam function serial_cb serial_cb with proto funciont(ts_resp_ctx, arg) return openssl.bn end ++@usage ++ function serial_cb(tsa,arg) ++ local bn = ... ++ return bn ++ end ++ local arg = {} ++ ts_resp_ctx:set_serial_cb(serial_cb, arg) ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_set_serial_cb) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- int cbref, argref; + TS_CB_ARG* arg = NULL; ++ int top = lua_gettop(L); ++ + luaL_checktype(L, 2, LUA_TFUNCTION); ++ arg = (TS_CB_ARG*)lua_newuserdata(L, sizeof(TS_CB_ARG)); + + lua_pushvalue(L, 2); +- cbref = luaL_ref(L, LUA_REGISTRYINDEX); +- lua_pushvalue(L, 3); +- argref = luaL_ref(L, LUA_REGISTRYINDEX); +- +- arg = (TS_CB_ARG*)lua_newuserdata(L, sizeof(TS_CB_ARG)); +- arg->callback = cbref; +- arg->cb_arg = argref; +- arg->L = L; +- lua_pushvalue(L, 1); +- arg->ctx = luaL_ref(L, LUA_REGISTRYINDEX); +- openssl_setvalue(L, ctx, "serial_cb"); ++ arg->callback = luaL_ref(L, LUA_REGISTRYINDEX); ++ if (top > 2) ++ lua_pushvalue(L, 3); ++ else ++ lua_pushnil(L); ++ arg->cb_arg = luaL_ref(L, LUA_REGISTRYINDEX); + +- TS_RESP_CTX_set_serial_cb(ctx, openssl_serial_cb, arg); ++ openssl_valueset(L, ctx, serial_cb_key); ++ TS_RESP_CTX_set_serial_cb(ctx, openssl_serial_cb, L); + return 0; + }; + + static int openssl_time_cb(TS_RESP_CTX *ctx, void *data, long *sec, long *usec) + { +- TS_CB_ARG *arg = (TS_CB_ARG*)data; +- lua_State* L = arg->L; + int err; +- (void) ctx; ++ TS_CB_ARG *arg; ++ lua_State* L = data; ++ ++ openssl_valueget(L, ctx, time_cb_key); ++ if (!lua_isuserdata(L, -1)) ++ { ++ TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, ++ "could not get current time"); ++ lua_pop(L, 1); /* remove openssl_valueget returned value */ ++ return 0; ++ } ++ arg = lua_touserdata(L, -1); ++ lua_pop(L, 1); /* remove openssl_valueget returned value */ ++ + lua_rawgeti(L, LUA_REGISTRYINDEX, arg->callback); +- lua_rawgeti(L, LUA_REGISTRYINDEX, arg->ctx); + lua_rawgeti(L, LUA_REGISTRYINDEX, arg->cb_arg); +- err = lua_pcall(L, 2, 2, 0); ++ err = lua_pcall(L, 1, 2, 0); + if (err == 0) + { +- if (lua_isnil(L, -2)) +- { +- lua_pop(L, 2); +- return 0; +- } +- else ++ if (lua_isnumber(L, -2)) + { + *sec = (long)luaL_checkinteger(L, -2); + *usec = (long)luaL_optinteger(L, -1, 0); +- lua_pop(L, 2); ++ lua_pop(L, 2); /* remove callback returned value */ + return 1; + } ++ lua_pop(L, 2); /* remove callback returned value */ ++ ++ TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, ++ "could not get current time"); ++ return 0; + } + else ++ { + lua_error(L); ++ } + return 0; + } + ++/*** ++set time callback function ++@function set_time_cb ++@tparam function time_cb serial_cb with proto funciont(ts_resp_ctx, arg) return sec, usec end ++@usage ++ function time_cb(tsa,arg) ++ local time = os.time() ++ local utime = nil ++ return time,utime ++ end ++ local arg = {} ++ ts_resp_ctx:set_time_cb(time_cb, arg) ++*/ + static LUA_FUNCTION(openssl_ts_resp_ctx_set_time_cb) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); +- int cbref, argref; + TS_CB_ARG* arg = NULL; ++ int top = lua_gettop(L); + luaL_checktype(L, 2, LUA_TFUNCTION); ++ arg = (TS_CB_ARG*)lua_newuserdata(L, sizeof(TS_CB_ARG)); + + lua_pushvalue(L, 2); +- cbref = luaL_ref(L, LUA_REGISTRYINDEX); +- lua_pushvalue(L, 3); +- argref = luaL_ref(L, LUA_REGISTRYINDEX); ++ arg->callback = luaL_ref(L, LUA_REGISTRYINDEX); ++ if (top > 2) ++ lua_pushvalue(L, 3); ++ else ++ lua_pushnil(L); ++ arg->cb_arg = luaL_ref(L, LUA_REGISTRYINDEX); + +- arg = (TS_CB_ARG*)lua_newuserdata(L, sizeof(TS_CB_ARG)); +- arg->callback = cbref; +- arg->cb_arg = argref; +- lua_pushvalue(L, 1); +- arg->ctx = luaL_ref(L, LUA_REGISTRYINDEX); +- arg->L = L; +- lua_rawsetp(L, LUA_REGISTRYINDEX, ctx); +- TS_RESP_CTX_set_time_cb(ctx, openssl_time_cb, arg); ++ openssl_valueset(L, ctx, time_cb_key); ++#if defined(LIBRESSL_VERSION_NUMBER) ++ ctx->time_cb = openssl_time_cb; ++ ctx->time_cb_data = L; ++#else ++ TS_RESP_CTX_set_time_cb(ctx, openssl_time_cb, L); ++#endif + return 0; + } + + static LUA_FUNCTION(openssl_ts_resp_ctx_gc) + { + TS_RESP_CTX *ctx = CHECK_OBJECT(1, TS_RESP_CTX, "openssl.ts_resp_ctx"); ++ openssl_valueget(L, ctx, time_cb_key); ++ if (lua_isuserdata(L, -1)) ++ { ++ TS_CB_ARG *arg = lua_touserdata(L, -1); ++ luaL_unref(L, LUA_REGISTRYINDEX, arg->callback); ++ luaL_unref(L, LUA_REGISTRYINDEX, arg->cb_arg); ++ } ++ lua_pop(L, 1); ++ openssl_valueget(L, ctx, serial_cb_key); ++ if (lua_isuserdata(L, -1)) ++ { ++ TS_CB_ARG *arg = lua_touserdata(L, -1); ++ luaL_unref(L, LUA_REGISTRYINDEX, arg->callback); ++ luaL_unref(L, LUA_REGISTRYINDEX, arg->cb_arg); ++ } ++ lua_pop(L, 1); + openssl_freevalue(L, ctx); + TS_RESP_CTX_free(ctx); + return 0; +@@ -1095,180 +1343,125 @@ static luaL_Reg ts_resp_ctx_funs[] = + + /********************************************************************/ + +-static LUA_FUNCTION(openssl_ts_verify_ctx_new) +-{ +- TS_VERIFY_CTX *ctx = NULL; +- if (lua_isnone(L, 1)) +- { +- ctx = TS_VERIFY_CTX_new(); +- ctx->flags |= TS_VFY_SIGNATURE; +- } +- else if (lua_isstring(L, 1)) +- { +- BIO* bio = load_bio_object(L, 1); +- TS_REQ* req = d2i_TS_REQ_bio(bio, NULL); +- BIO_free(bio); +- if (req) +- { +- ctx = TS_REQ_to_TS_VERIFY_CTX(req, NULL); +- TS_REQ_free(req); +- } +- else +- { +- luaL_argerror(L, 1, "must be ts_req data or object or nil"); +- } +- } +- else +- { +- TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); +- ctx = TS_REQ_to_TS_VERIFY_CTX(req, NULL); +- } +- if (ctx) +- { +- PUSH_OBJECT(ctx, "openssl.ts_verify_ctx"); +- } +- else +- lua_pushnil(L); +- return 1; +-} +- ++/*** ++openssl.ts_verify_ctx object ++@type ts_verify_ctx ++*/ ++/*** ++get x509_store cacerts ++@function store ++@treturn stack_of_x509 ++*/ ++/*** ++set x509_store cacerts ++@tparam x509_store cacerts ++@treturn boolean result ++@function store ++*/ + static int openssl_ts_verify_ctx_store(lua_State*L) + { + TS_VERIFY_CTX *ctx = CHECK_OBJECT(1, TS_VERIFY_CTX, "openssl.ts_verify_ctx"); +- if (lua_isnone(L, 2)) +- { +- /* +- if (ctx->store) +- { +- STACK_OF(X509) *cas = X509_STORE_get1_certs(ctx->store, NULL); +- openssl_sk_x509_totable(L, cas); +- } +- else +- */ +- lua_pushnil(L); +- } +- else +- { +- X509_STORE* store = CHECK_OBJECT(2, X509_STORE, "openssl.x509_store"); +- if (ctx->store) +- openssl_xstore_free(ctx->store); +- +- CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); +- ctx->store = store; +- ctx->flags |= TS_VFY_SIGNER | TS_VFY_SIGNATURE; +- lua_pushboolean(L, 1); +- } +- return 1; +-} +- +-static int openssl_ts_verify_ctx_certs(lua_State*L) +-{ +- TS_VERIFY_CTX *ctx = CHECK_OBJECT(1, TS_VERIFY_CTX, "openssl.ts_verify_ctx"); +- if (lua_isnone(L, 2)) +- { +- if (ctx->certs) +- { +- openssl_sk_x509_totable(L, ctx->certs); +- } +- else +- lua_pushnil(L); +- } +- else +- { +- if (ctx->certs) +- sk_X509_pop_free(ctx->certs, X509_free); +- +- ctx->certs = openssl_sk_x509_fromtable(L, 2); +- lua_pushboolean(L, 1); +- } +- return 1; ++ X509_STORE* store = CHECK_OBJECT(2, X509_STORE, "openssl.x509_store"); ++ X509_STORE_up_ref(store); ++ TS_VERIFY_CTX_set_store(ctx, store); ++ return 0; + } + ++/*** ++get flags ++@function flags ++@treturn integer flags ++*/ ++/*** ++set flags ++@function flags ++@tparam integer flags ++@treturn boolean result ++*/ + static int openssl_ts_verify_ctx_flags(lua_State*L) + { + TS_VERIFY_CTX *ctx = CHECK_OBJECT(1, TS_VERIFY_CTX, "openssl.ts_verify_ctx"); +- if (lua_isnone(L, 2)) +- { +- lua_pushinteger(L, ctx->flags); +- return 1; +- } +- else +- { +- ctx->flags = luaL_checkinteger(L, 2); +- } +- return 0; ++ int flags = luaL_checkint(L, 2); ++ int add = lua_isnoneornil(L, 3) ? 0 : lua_toboolean(L, 3); ++ if (add) ++ flags = TS_VERIFY_CTX_add_flags(ctx, flags); ++ else ++ flags = TS_VERIFY_CTX_set_flags(ctx, flags); ++ lua_pushinteger(L, flags); ++ return 1; + } + ++/*** ++get data ++@function data ++@treturn bio data object ++*/ ++/*** ++set data ++@function data ++@tparam bio data object ++@treturn boolean result ++*/ + static int openssl_ts_verify_ctx_data(lua_State*L) + { + TS_VERIFY_CTX *ctx = CHECK_OBJECT(1, TS_VERIFY_CTX, "openssl.ts_verify_ctx"); +- if (lua_isnone(L, 2)) +- { +- if (ctx->data) +- { +- BIO* bio = ctx->data; +- CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); +- PUSH_OBJECT(bio, "openssl.bio"); +- } +- else +- lua_pushnil(L); +- return 1; +- } +- else +- { +- BIO* bio = load_bio_object(L, 2); +- if (ctx->data) +- BIO_free(ctx->data); +- ctx->data = bio; +- ctx->flags |= TS_VFY_DATA; +- lua_pushboolean(L, 1); +- return 1; +- } ++ BIO* bio = load_bio_object(L, 2); ++ BIO_up_ref(bio); ++ TS_VERIFY_CTX_set_data(ctx, bio); ++ return 0; + } + ++/*** ++get imprint ++@function imprint ++@treturn string imprint ++*/ ++/*** ++set imprint ++@function imprint ++@tparam string imprint ++@treturn boolean result ++*/ + static int openssl_ts_verify_ctx_imprint(lua_State*L) + { + TS_VERIFY_CTX *ctx = CHECK_OBJECT(1, TS_VERIFY_CTX, "openssl.ts_verify_ctx"); +- if (lua_isnone(L, 2)) +- { +- lua_pushlstring(L, (const char*)ctx->imprint, ctx->imprint_len); +- return 1; +- } +- else +- { +- size_t imprint_len; +- const char* imprint = luaL_checklstring(L, 2, &imprint_len); +- +- ctx->imprint = OPENSSL_malloc(imprint_len); +- memcpy(ctx->imprint, imprint, imprint_len);; +- ctx->imprint_len = imprint_len; +- ctx->flags |= TS_VFY_IMPRINT; +- lua_pushboolean(L, 1); +- return 1; +- } ++ size_t imprint_len; ++ const char* imprint = luaL_checklstring(L, 2, &imprint_len); ++ unsigned char* to = OPENSSL_malloc(imprint_len); ++ memcpy(to, imprint, imprint_len); ++ TS_VERIFY_CTX_set_imprint(ctx, to, imprint_len); ++ return 0; + } + + static LUA_FUNCTION(openssl_ts_verify_ctx_gc) + { + TS_VERIFY_CTX *ctx = CHECK_OBJECT(1, TS_VERIFY_CTX, "openssl.ts_verify_ctx"); +- if (ctx->store) +- openssl_xstore_free(ctx->store); +- ++ /* hack openssl bugs */ ++#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER) ++ if (ctx->store->references > 1) ++ CRYPTO_add(&ctx->store->references, -1, CRYPTO_LOCK_X509_STORE); + ctx->store = NULL; ++#endif + TS_VERIFY_CTX_free(ctx); + return 0; + } + ++/*** ++verify ts_resp object, pkcs7 token or ts_resp data ++@function verify ++@tparam ts_resp|pkcs7|string data ++@treturn boolean result ++*/ + static LUA_FUNCTION(openssl_ts_verify_ctx_verify) + { + TS_VERIFY_CTX *ctx = CHECK_OBJECT(1, TS_VERIFY_CTX, "openssl.ts_verify_ctx"); + int ret = 0; +- if (auxiliar_isclass(L, "openssl.ts_resp", 2)) ++ if (auxiliar_getclassudata(L, "openssl.ts_resp", 2)) + { + TS_RESP *response = CHECK_OBJECT(2, TS_RESP, "openssl.ts_resp"); + ret = TS_RESP_verify_response(ctx, response); + } +- else if (auxiliar_isclass(L, "openssl.pkcs7", 2)) ++ else if (auxiliar_getclassudata(L, "openssl.pkcs7", 2)) + { + PKCS7 *token = CHECK_OBJECT(2, PKCS7, "openssl.pkcs7"); + ret = TS_RESP_verify_token(ctx, token); +@@ -1296,12 +1489,10 @@ static LUA_FUNCTION(openssl_ts_verify_ct + static luaL_Reg ts_verify_ctx_funs[] = + { + {"store", openssl_ts_verify_ctx_store}, +- {"certs", openssl_ts_verify_ctx_certs}, + {"flags", openssl_ts_verify_ctx_flags}, + {"verify", openssl_ts_verify_ctx_verify}, + {"data", openssl_ts_verify_ctx_data}, + {"imprint", openssl_ts_verify_ctx_imprint}, +-// {"info", openssl_ts_verify_ctx_info}, + + {"__tostring", auxiliar_tostring}, + {"__gc", openssl_ts_verify_ctx_gc}, +@@ -1309,17 +1500,6 @@ static luaL_Reg ts_verify_ctx_funs[] = + { NULL, NULL } + }; + +-static luaL_Reg R[] = +-{ +- {"req_new", openssl_ts_req_new}, +- {"req_read", openssl_ts_req_read}, +- {"resp_read", openssl_ts_resp_read}, +- +- {"resp_ctx_new", openssl_ts_resp_ctx_new }, +- {"verify_ctx_new", openssl_ts_verify_ctx_new }, +- +- {NULL, NULL} +-}; + #endif + int luaopen_ts(lua_State *L) + { +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/pkcs12.c luvi-src-v2.7.6/deps/lua-openssl/src/pkcs12.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/pkcs12.c 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/pkcs12.c 2019-02-13 11:53:24.298459641 +0100 +@@ -11,6 +11,25 @@ + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + ++/*** ++Provide pkcs12 function in lua. ++ ++@module pkcs12 ++@usage ++ pkcs12 = require('openssl').pkcs12 ++*/ ++ ++/*** ++create and export pkcs12 data ++ ++@function export ++@tparam x509 cert ++@tparam evp_pkey pkey ++@tparam string password ++@tparam[opt] string friendlyname ++@tparam[opt] table|stak_of_x509 extracerts ++@treturn string data ++*/ + static LUA_FUNCTION(openssl_pkcs12_export) + { + X509 * cert = CHECK_OBJECT(1, X509, "openssl.x509"); +@@ -65,6 +84,14 @@ static LUA_FUNCTION(openssl_pkcs12_expor + return ret; + } + ++/*** ++parse pkcs12 data as lua table ++ ++@function read ++@tparam string|bio input pkcs12 content ++@tparam string password for pkcs12 ++@treturn table result contain 'cert', 'pkey', 'extracerts' keys ++*/ + static LUA_FUNCTION(openssl_pkcs12_read) + { + PKCS12 * p12 = NULL; +@@ -114,7 +141,7 @@ static LUA_FUNCTION(openssl_pkcs12_read) + static luaL_Reg R[] = + { + {"read", openssl_pkcs12_read }, +- {"export", openssl_pkcs12_export }, ++ {"export", openssl_pkcs12_export }, + + {NULL, NULL} + }; +@@ -124,7 +151,7 @@ int luaopen_pkcs12(lua_State *L) + lua_newtable(L); + luaL_setfuncs(L, R, 0); + +- lua_pushliteral(L, "version"); /** version */ ++ lua_pushliteral(L, "version"); + lua_pushliteral(L, MYVERSION); + lua_settable(L, -3); + +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/pkcs7.c luvi-src-v2.7.6/deps/lua-openssl/src/pkcs7.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/pkcs7.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/pkcs7.c 2019-02-13 11:53:24.298459641 +0100 +@@ -1,10 +1,10 @@ +-/*=========================================================================*\ +-* pkcs7.c +-* PKCS7 module for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++PKCS7 module for lua-openssl binding + ++@module pkcs7 ++@usage ++ pkcs7 = require('openssl').pkcs7 ++*/ + #include "openssl.h" + #include "private.h" + +@@ -12,6 +12,16 @@ + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + ++/*** ++read string or bio object, which include pkcs7 content ++ ++@function read ++@tparam bio|string input ++@tparam[opt='auto'] format allow 'auto','der','pem','smime' ++ auto will only try 'der' or 'pem' ++@treturn pkcs7 object or nil ++@treturn string content exist only smime format ++*/ + static LUA_FUNCTION(openssl_pkcs7_read) + { + BIO* bio = load_bio_object(L, 1); +@@ -27,12 +37,12 @@ static LUA_FUNCTION(openssl_pkcs7_read) + if (fmt == FORMAT_DER) + { + p7 = d2i_PKCS7_bio(bio, NULL); +- BIO_reset(bio); ++ (void)BIO_reset(bio); + } + else if (fmt == FORMAT_PEM) + { + p7 = PEM_read_bio_PKCS7(bio, NULL, NULL, NULL); +- BIO_reset(bio); ++ (void)BIO_reset(bio); + } + else if (fmt == FORMAT_SMIME) + { +@@ -57,11 +67,18 @@ static LUA_FUNCTION(openssl_pkcs7_read) + } + + #if OPENSSL_VERSION_NUMBER > 0x10000000L ++/*** ++create new empty pkcs7 object, which support flexble sign methods. + ++@function new ++@tparam[opt=NID_pkcs7_signed] int oid given pkcs7 type ++@tparam[opt=NID_pkcs7_data] int content given pkcs7 content type ++@treturn pkcs7 object ++*/ + static LUA_FUNCTION(openssl_pkcs7_new) + { + int type = luaL_optint(L, 1, NID_pkcs7_signed); +- int content_nid = luaL_optint(L, 1, NID_pkcs7_data); ++ int content_nid = luaL_optint(L, 2, NID_pkcs7_data); + + PKCS7 *p7 = PKCS7_new(); + if (p7) +@@ -81,23 +98,6 @@ static LUA_FUNCTION(openssl_pkcs7_new) + return 0; + } + +-static LUA_FUNCTION(openssl_pkcs7_sign_add_signer) +-{ +- PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); +- X509 *signcert = CHECK_OBJECT(2, X509, "openssl.x509"); +- EVP_PKEY *pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); +- const EVP_MD* md = get_digest(L, 4); +- long flags = luaL_optint(L, 5, 0); +- PKCS7_SIGNER_INFO *signer = 0; +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 3, "must be private key"); +- luaL_argcheck(L, X509_check_private_key(signcert, pkey), 3, +- "sigcert and private key not match"); +- +- signer = PKCS7_sign_add_signer(p7, signcert, pkey, md, flags); +- (void) signer; +- return openssl_pushresult(L, signcert != NULL ? 1 : 0); +-} +- + static LUA_FUNCTION(openssl_pkcs7_add) + { + PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); +@@ -107,10 +107,10 @@ static LUA_FUNCTION(openssl_pkcs7_add) + luaL_argcheck(L, lua_isuserdata(L, 2), 2, "must supply certificate or crl object"); + for (i = 2; i <= n; i++) + { +- luaL_argcheck(L, auxiliar_isclass(L, "openssl.x509", i) || auxiliar_isclass(L, "openssl.x509_crl", i), ++ luaL_argcheck(L, auxiliar_getclassudata(L, "openssl.x509", i) || auxiliar_getclassudata(L, "openssl.x509_crl", i), + i, "must supply certificate or crl object"); + +- if (auxiliar_isclass(L, "openssl.x509", i)) ++ if (auxiliar_getclassudata(L, "openssl.x509", i)) + { + X509* x = CHECK_OBJECT(i, X509, "openssl.x509"); + ret = PKCS7_add_certificate(p7, x); +@@ -179,12 +179,11 @@ static BIO *PKCS7_find_digest(EVP_MD_CTX + return bio; + bio = BIO_next(bio); + } +- return NULL; + } + + static int PKCS7_SIGNER_INFO_sign_0(PKCS7_SIGNER_INFO *si) + { +- EVP_MD_CTX mctx; ++ EVP_MD_CTX *mctx; + EVP_PKEY_CTX *pctx; + unsigned char *abuf = NULL; + int alen; +@@ -195,8 +194,9 @@ static int PKCS7_SIGNER_INFO_sign_0(PKCS + if (md == NULL) + return 0; + +- EVP_MD_CTX_init(&mctx); +- if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) ++ mctx = EVP_MD_CTX_new(); ++ EVP_MD_CTX_init(mctx); ++ if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, +@@ -210,17 +210,17 @@ static int PKCS7_SIGNER_INFO_sign_0(PKCS + ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); + if (!abuf) + goto err; +- if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) ++ if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0) + goto err; + OPENSSL_free(abuf); + abuf = NULL; +- if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) ++ if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0) + goto err; + abuf = OPENSSL_malloc(siglen); + if (!abuf) + goto err; + +- if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) ++ if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) + goto err; + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) +@@ -229,7 +229,7 @@ static int PKCS7_SIGNER_INFO_sign_0(PKCS + goto err; + } + +- EVP_MD_CTX_cleanup(&mctx); ++ EVP_MD_CTX_free(mctx); + + ASN1_STRING_set0(si->enc_digest, abuf, siglen); + +@@ -238,7 +238,7 @@ static int PKCS7_SIGNER_INFO_sign_0(PKCS + err: + if (abuf) + OPENSSL_free(abuf); +- EVP_MD_CTX_cleanup(&mctx); ++ EVP_MD_CTX_free(mctx); + return 0; + + } +@@ -307,34 +307,31 @@ static char *memdup(const char *src, siz + return buffer; + } + +-static LUA_FUNCTION(openssl_pkcs7_sign_digest) +-{ +- PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); +- size_t l; +- const char* data = luaL_checklstring(L, 2, &l); +- long flags = luaL_optint(L, 3, 0); +- int hash = lua_isnoneornil(L, 4) ? 0 : lua_toboolean(L, 4); + ++static int openssl_pkcs7_dataFinal(PKCS7 *p7, BIO *bio) ++{ + int ret = 0; + int i, j; +- +- const EVP_MD* md; ++ BIO *btmp; + PKCS7_SIGNER_INFO *si; +- EVP_MD_CTX mdc; ++ EVP_MD_CTX *mdc, *ctx_tmp; + STACK_OF(X509_ATTRIBUTE) *sk; + STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; + ASN1_OCTET_STRING *os = NULL; + +- if (p7->d.ptr == NULL) ++ if (p7 == NULL) + { +- luaL_error(L, "pkcs7 without content"); ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + +- flags |= PKCS7_DETACHED; +- PKCS7_set_detached(p7, 1); +- +- EVP_MD_CTX_init(&mdc); ++ if (p7->d.ptr == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); ++ return 0; ++ } ++ ctx_tmp = EVP_MD_CTX_new(); ++ EVP_MD_CTX_init(ctx_tmp); + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + +@@ -349,7 +346,11 @@ static LUA_FUNCTION(openssl_pkcs7_sign_d + os = p7->d.signed_and_enveloped->enc_data->enc_data; + if (!os) + { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + os = M_ASN1_OCTET_STRING_new(); ++#else ++ os = ASN1_OCTET_STRING_new(); ++#endif + if (!os) + { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); +@@ -363,7 +364,11 @@ static LUA_FUNCTION(openssl_pkcs7_sign_d + os = p7->d.enveloped->enc_data->enc_data; + if (!os) + { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + os = M_ASN1_OCTET_STRING_new(); ++#else ++ os = ASN1_OCTET_STRING_new(); ++#endif + if (!os) + { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); +@@ -378,7 +383,11 @@ static LUA_FUNCTION(openssl_pkcs7_sign_d + /* If detached data then the content is excluded */ + if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) + { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + M_ASN1_OCTET_STRING_free(os); ++#else ++ ASN1_OCTET_STRING_free(os); ++#endif + os = NULL; + p7->d.sign->contents->d.data = NULL; + } +@@ -389,7 +398,11 @@ static LUA_FUNCTION(openssl_pkcs7_sign_d + /* If detached data then the content is excluded */ + if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) + { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + M_ASN1_OCTET_STRING_free(os); ++#else ++ ASN1_OCTET_STRING_free(os); ++#endif + os = NULL; + p7->d.digest->contents->d.data = NULL; + } +@@ -407,24 +420,21 @@ static LUA_FUNCTION(openssl_pkcs7_sign_d + si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); + if (si->pkey == NULL) + continue; ++ + j = OBJ_obj2nid(si->digest_alg->algorithm); +- md = EVP_get_digestbynid(j); +- EVP_DigestInit_ex(&mdc, md, NULL); + +- if (hash) +- { +- if (l == (size_t) mdc.digest->ctx_size) +- { +- memcpy(mdc.md_data, data, l); +- } +- else +- { +- EVP_MD_CTX_cleanup(&mdc); +- luaL_argerror(L, 2, "data with wrong length"); +- } +- } +- else +- EVP_DigestUpdate(&mdc, data, l); ++ btmp = bio; ++ ++ btmp = PKCS7_find_digest(&mdc, btmp, j); ++ ++ if (btmp == NULL) ++ goto err; ++ ++ /* ++ * We now have the EVP_MD_CTX, lets do the signing. ++ */ ++ if (!EVP_MD_CTX_copy_ex(ctx_tmp, mdc)) ++ goto err; + + sk = si->auth_attr; + +@@ -434,7 +444,7 @@ static LUA_FUNCTION(openssl_pkcs7_sign_d + */ + if (sk_X509_ATTRIBUTE_num(sk) > 0) + { +- if (!do_pkcs7_signed_attrib(si, &mdc)) ++ if (!do_pkcs7_signed_attrib(si, ctx_tmp)) + goto err; + } + else +@@ -446,7 +456,7 @@ static LUA_FUNCTION(openssl_pkcs7_sign_d + if (!abuf) + goto err; + +- if (!EVP_SignFinal(&mdc, abuf, &abuflen, si->pkey)) ++ if (!EVP_SignFinal(ctx_tmp, abuf, &abuflen, si->pkey)) + { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); + goto err; +@@ -459,20 +469,16 @@ static LUA_FUNCTION(openssl_pkcs7_sign_d + { + unsigned char md_data[EVP_MAX_MD_SIZE]; + unsigned int md_len; +- md = EVP_get_digestbynid(OBJ_obj2nid(p7->d.digest->md->algorithm)); +- EVP_DigestInit_ex(&mdc, md, NULL); +- if (l == (size_t) mdc.digest->ctx_size) +- { +- memcpy(mdc.md_data, data, l); +- } +- else +- { +- EVP_MD_CTX_cleanup(&mdc); +- luaL_error(L, "data with wrong data"); +- } +- if (!EVP_DigestFinal_ex(&mdc, md_data, &md_len)) ++ if (!PKCS7_find_digest(&mdc, bio, ++ OBJ_obj2nid(p7->d.digest->md->algorithm))) + goto err; ++ if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) ++ goto err; ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); ++#else ++ ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); ++#endif + } + + if (!PKCS7_is_detached(p7)) +@@ -485,16 +491,67 @@ static LUA_FUNCTION(openssl_pkcs7_sign_d + goto err; + if (!(os->flags & ASN1_STRING_FLAG_NDEF)) + { +- char *cont = memdup(data, l); +- long contlen = l; +- ASN1_STRING_set0(os, (unsigned char *) cont, contlen); ++ char *cont; ++ long contlen; ++ btmp = BIO_find_type(bio, BIO_TYPE_MEM); ++ if (btmp == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); ++ goto err; ++ } ++ contlen = BIO_get_mem_data(btmp, &cont); ++ /* ++ * Mark the BIO read only then we can use its copy of the data ++ * instead of making an extra copy. ++ */ ++ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); ++ BIO_set_mem_eof_return(btmp, 0); ++ ASN1_STRING_set0(os, (unsigned char *)cont, contlen); + } + } +- + ret = 1; + err: +- EVP_MD_CTX_cleanup(&mdc); +- return openssl_pushresult(L, ret); ++ EVP_MD_CTX_free(ctx_tmp); ++ return (ret); ++} ++ ++ ++static int openssl_pkcs7_final(lua_State *L) ++{ ++ PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); ++ BIO *data = load_bio_object(L, 2); ++ int flags = luaL_optint(L, 3, 0); ++ ++ BIO *p7bio = PKCS7_dataInit(p7, NULL); ++ int ret = 0; ++ ++ if (p7bio == NULL) ++ { ++ lua_pushnil(L); ++ lua_pushstring(L, "PKCS7_dataInit fail"); ++ ret = 2; ++ } ++ else ++ { ++ SMIME_crlf_copy(data, p7bio, flags); ++ ++ (void)BIO_flush(p7bio); ++ ++ if (!openssl_pkcs7_dataFinal(p7, p7bio)) ++ { ++ lua_pushnil(L); ++ lua_pushstring(L, "PKCS7_dataFinal fail"); ++ ret = 2; ++ } ++ else ++ { ++ ret = 1; ++ lua_pushboolean(L, 1); ++ } ++ BIO_free_all(p7bio); ++ } ++ ++ return ret; + } + + int PKCS7_signatureVerify_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si, X509 *x509, +@@ -502,14 +559,16 @@ int PKCS7_signatureVerify_digest(PKCS7 * + { + ASN1_OCTET_STRING *os; + const EVP_MD* md; +- EVP_MD_CTX mdc, mdc_tmp; ++ EVP_MD_CTX *mdc, *mdc_tmp; + int ret = 0, i; + int md_type; + STACK_OF(X509_ATTRIBUTE) *sk; + EVP_PKEY *pkey = NULL; + +- EVP_MD_CTX_init(&mdc); +- EVP_MD_CTX_init(&mdc_tmp); ++ mdc = EVP_MD_CTX_new(); ++ mdc_tmp = EVP_MD_CTX_new(); ++ EVP_MD_CTX_init(mdc); ++ EVP_MD_CTX_init(mdc_tmp); + if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) + { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); +@@ -518,15 +577,27 @@ int PKCS7_signatureVerify_digest(PKCS7 * + + md_type = OBJ_obj2nid(si->digest_alg->algorithm); + md = EVP_get_digestbynid(md_type); ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + if (!md || !data || (hash && len != (size_t) md->ctx_size) ) + goto err; + +- if (!EVP_DigestInit_ex(&mdc, md, NULL)) ++ if (!EVP_DigestInit_ex(mdc, md, NULL)) ++ goto err; ++ if (hash) ++ memcpy(mdc->md_data, data, len); ++ else ++ EVP_DigestUpdate(mdc, data, len); ++#else ++ if (!md || !data || (hash && len != (size_t)EVP_MD_meth_get_app_datasize(md)) ) ++ goto err; ++ ++ if (!EVP_DigestInit_ex(mdc, md, NULL)) + goto err; + if (hash) +- memcpy(mdc.md_data, data, len); ++ memcpy(EVP_MD_CTX_md_data(mdc), data, len); + else +- EVP_DigestUpdate(&mdc, data, len); ++ EVP_DigestUpdate(mdc, data, len); ++#endif + + pkey = X509_get_pubkey(x509); + if (!pkey) +@@ -538,7 +609,7 @@ int PKCS7_signatureVerify_digest(PKCS7 * + * mdc is the digest ctx that we want, unless there are attributes, in + * which case the digest is the signed attributes + */ +- if (!EVP_MD_CTX_copy_ex(&mdc_tmp, &mdc)) ++ if (!EVP_MD_CTX_copy_ex(mdc_tmp, mdc)) + goto err; + sk = si->auth_attr; + if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) +@@ -548,7 +619,7 @@ int PKCS7_signatureVerify_digest(PKCS7 * + int alen; + ASN1_OCTET_STRING *message_digest; + +- if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) ++ if (!EVP_DigestFinal_ex(mdc_tmp, md_dat, &md_len)) + goto err; + message_digest = PKCS7_digest_from_attributes(sk); + if (!message_digest) +@@ -564,7 +635,7 @@ int PKCS7_signatureVerify_digest(PKCS7 * + ret = -1; + goto err; + } +- if (!EVP_DigestVerifyInit(&mdc_tmp, NULL, EVP_get_digestbynid(md_type), NULL, pkey)) ++ if (!EVP_DigestVerifyInit(mdc_tmp, NULL, EVP_get_digestbynid(md_type), NULL, pkey)) + goto err; + + alen = ASN1_item_i2d((ASN1_VALUE *) sk, &abuf, +@@ -575,14 +646,14 @@ int PKCS7_signatureVerify_digest(PKCS7 * + ret = -1; + goto err; + } +- if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) ++ if (!EVP_VerifyUpdate(mdc_tmp, abuf, alen)) + goto err; + + OPENSSL_free(abuf); + } + + os = si->enc_digest; +- i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); ++ i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey); + if (i <= 0) + { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); +@@ -593,118 +664,25 @@ int PKCS7_signatureVerify_digest(PKCS7 * + ret = 1; + err: + EVP_PKEY_free(pkey); +- EVP_MD_CTX_cleanup(&mdc); +- EVP_MD_CTX_cleanup(&mdc_tmp); ++ EVP_MD_CTX_free(mdc); ++ EVP_MD_CTX_free(mdc_tmp); + + return (ret); + } + +-static LUA_FUNCTION(openssl_pkcs7_verify_digest) +-{ +- PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); +- STACK_OF(X509) *certs = lua_isnoneornil(L, 2) ? NULL : openssl_sk_x509_fromtable(L, 2); +- X509_STORE *store = lua_isnoneornil(L, 3) ? NULL : CHECK_OBJECT(3, X509_STORE, "openssl.x509_store"); +- size_t len; +- const char* data = luaL_checklstring(L, 4, &len); +- long flags = luaL_optint(L, 5, 0); +- int hash = lua_isnoneornil(L, 6) ? 0 : lua_toboolean(L, 6); +- +- STACK_OF(X509) *signers; +- X509 *signer; +- STACK_OF(PKCS7_SIGNER_INFO) *sinfos; +- PKCS7_SIGNER_INFO *si; +- X509_STORE_CTX cert_ctx; +- +- int i, j = 0, k, ret = 0; +- +- if (!PKCS7_type_is_signed(p7)) +- { +- luaL_error(L, "pkcs7 must be signedData"); +- } +- +- /* Check for no data and no content: no data to verify signature */ +- if (!PKCS7_get_detached(p7)) +- { +- luaL_error(L, "pkcs7 must be detached signedData"); +- } +- +- +- sinfos = PKCS7_get_signer_info(p7); +- if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) +- { +- luaL_error(L, "pkcs7 signedData without signature"); +- } +- +- signers = PKCS7_get0_signers(p7, certs, flags); +- if (!signers) +- { +- luaL_error(L, "pkcs7 signedData without signers"); +- } +- +- if (!store) +- flags |= PKCS7_NOVERIFY; +- +- /* Now verify the certificates */ +- if (!(flags & PKCS7_NOVERIFY)) +- for (k = 0; k < sk_X509_num(signers); k++) +- { +- signer = sk_X509_value(signers, k); +- if (!(flags & PKCS7_NOCHAIN)) +- { +- if (!X509_STORE_CTX_init(&cert_ctx, store, signer, +- p7->d.sign->cert)) +- { +- PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); +- goto err; +- } +- X509_STORE_CTX_set_default(&cert_ctx, "smime_sign"); +- } +- else if (!X509_STORE_CTX_init(&cert_ctx, store, signer, NULL)) +- { +- PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); +- goto err; +- } +- if (!(flags & PKCS7_NOCRL)) +- X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); +- i = X509_verify_cert(&cert_ctx); +- if (i <= 0) +- j = X509_STORE_CTX_get_error(&cert_ctx); +- X509_STORE_CTX_cleanup(&cert_ctx); +- if (i <= 0) +- { +- PKCS7err(PKCS7_F_PKCS7_VERIFY, +- PKCS7_R_CERTIFICATE_VERIFY_ERROR); +- ERR_add_error_data(2, "Verify error:", +- X509_verify_cert_error_string(j)); +- goto err; +- } +- /* Check for revocation status here */ +- } +- +- /* Now Verify All Signatures */ +- if (!(flags & PKCS7_NOSIGS)) +- for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) +- { +- si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); +- signer = sk_X509_value(signers, i); +- j = PKCS7_signatureVerify_digest(p7, si, signer, +- (const unsigned char*) data, len, hash); +- if (j <= 0) +- { +- PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE); +- goto err; +- } +- } +- ret = 1; +- +-err: +- if (certs) +- sk_X509_pop_free(certs, X509_free); +- sk_X509_free(signers); +- return openssl_pushresult(L, ret); +-} + #endif + ++/*** ++sign message with signcert and signpkey to create pkcs7 object ++ ++@function sign ++@tparam string|bio msg ++@tparam x509 signcert ++@tparam evp_pkey signkey ++@tparam[opt] stack_of_x509 cacerts ++@tparam[opt=0] number flags ++@treturn pkcs7 object ++*/ + static LUA_FUNCTION(openssl_pkcs7_sign) + { + BIO *in = load_bio_object(L, 1); +@@ -713,7 +691,6 @@ static LUA_FUNCTION(openssl_pkcs7_sign) + STACK_OF(X509) *others = lua_isnoneornil(L, 4) ? 0 : openssl_sk_x509_fromtable(L, 4); + long flags = luaL_optint(L, 5, 0); + PKCS7 *p7 = NULL; +- luaL_argcheck(L, openssl_pkey_is_private(privkey), 3, "must be private key"); + + if (!X509_check_private_key(cert, privkey)) + luaL_error(L, "sigcert and private key not match"); +@@ -734,6 +711,18 @@ static LUA_FUNCTION(openssl_pkcs7_sign) + return 0; + } + ++/*** ++verify pkcs7 object, and return msg content, follow by singers ++ ++@function verify ++@tparam pkcs7 in ++@tparam[opt] stack_of_x509 signercerts ++@tparam[opt] x509_store cacerts ++@tparam[opt] string|bio msg ++@tparam[opt=0] number flags ++@treturn[1] string content ++@treturn[1] boolean result ++*/ + static LUA_FUNCTION(openssl_pkcs7_verify) + { + int ret = 0; +@@ -741,10 +730,14 @@ static LUA_FUNCTION(openssl_pkcs7_verify + STACK_OF(X509) *signers = lua_isnoneornil(L, 2) ? NULL : openssl_sk_x509_fromtable(L, 2); + X509_STORE *store = lua_isnoneornil(L, 3) ? NULL : CHECK_OBJECT(3, X509_STORE, "openssl.x509_store"); + BIO* in = lua_isnoneornil(L, 4) ? NULL : load_bio_object(L, 4); +- long flags = luaL_optint(L, 5, 0); +- BIO* out = BIO_new(BIO_s_mem()); ++ long flags = luaL_optint(L, 5, PKCS7_DETACHED); ++ BIO* out = NULL; ++ + if (!store) + flags |= PKCS7_NOVERIFY; ++ if ((flags&PKCS7_DETACHED) != 0) ++ out = BIO_new(BIO_s_mem()); ++ + if (PKCS7_verify(p7, signers, store, in, out, flags) == 1) + { + if (out && (flags & PKCS7_DETACHED) == 0) +@@ -773,6 +766,15 @@ static LUA_FUNCTION(openssl_pkcs7_verify + return ret; + } + ++/*** ++encrypt message with recipcerts certificates return encrypted pkcs7 object ++ ++@function encrypt ++@tparam string|bio msg ++@tparam stack_of_x509 recipcerts ++@tparam[opt='rc4'] string|evp_cipher cipher ++@tparam[opt] number flags ++*/ + static LUA_FUNCTION(openssl_pkcs7_encrypt) + { + PKCS7 * p7 = NULL; +@@ -801,6 +803,15 @@ static LUA_FUNCTION(openssl_pkcs7_encryp + return 1; + } + ++/*** ++decrypt encrypted pkcs7 message ++ ++@function decrypt ++@tparam pkcs7 input ++@tparam x509 recipcert ++@tparam evp_pkey recipkey ++@treturn string decrypt message ++*/ + static LUA_FUNCTION(openssl_pkcs7_decrypt) + { + PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); +@@ -821,7 +832,11 @@ static LUA_FUNCTION(openssl_pkcs7_decryp + return 1; + } + +-/*** pkcs7 object method ***/ ++/*** ++openssl.pkcs7 object ++ ++@type pkcs7 ++*/ + static LUA_FUNCTION(openssl_pkcs7_gc) + { + PKCS7* p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); +@@ -829,17 +844,26 @@ static LUA_FUNCTION(openssl_pkcs7_gc) + return 0; + } + ++/*** ++export pkcs7 as string ++ ++@function export ++@tparam[opt='pem'] string support export as 'pem' or 'der' format, default is 'pem' ++@treturn string ++*/ + static LUA_FUNCTION(openssl_pkcs7_export) + { +- int pem; + PKCS7 * p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); +- int top = lua_gettop(L); + BIO* bio_out = NULL; +- +- pem = top > 1 ? lua_toboolean(L, 2) : 1; ++ int fmt = lua_type(L, 2); ++ luaL_argcheck(L, fmt == LUA_TSTRING || fmt == LUA_TNONE, 2, ++ "only accept 'pem','der' or none"); ++ fmt = luaL_checkoption(L, 2, "pem", format); ++ luaL_argcheck(L, fmt == FORMAT_PEM || fmt == FORMAT_DER, 2, ++ "only accept pem or der, default is pem"); + + bio_out = BIO_new(BIO_s_mem()); +- if (pem) ++ if (fmt == FORMAT_PEM) + { + + if (PEM_write_bio_PKCS7(bio_out, p7)) +@@ -901,19 +925,28 @@ static int openssl_push_pkcs7_signer_inf + + if (info->pkey) + { +- CRYPTO_add(&info->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); ++ EVP_PKEY_up_ref(info->pkey); + AUXILIAR_SETOBJECT(L, info->pkey, "openssl.evp_pkey", -1, "pkey"); + } + return 1; + } + +-static LUA_FUNCTION(openssl_pkcs7_signer_info_gc) ++static LUA_FUNCTION(openssl_pkcs7_type) + { +- PKCS7_SIGNER_INFO *info = CHECK_OBJECT(1, PKCS7_SIGNER_INFO, "openssl.pkcs7_signer_info"); +- PKCS7_SIGNER_INFO_free(info); +- return 0; ++ PKCS7 * p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); ++ int i = OBJ_obj2nid(p7->type); ++ ++ lua_pushstring(L, OBJ_nid2sn(i)); ++ lua_pushstring(L, OBJ_nid2ln(i)); ++ return 2; + } + ++/*** ++export pkcs7 as a string ++ ++@function parse ++@treturn table a table has pkcs7 infomation, include type,and other things relate to types ++*/ + static LUA_FUNCTION(openssl_pkcs7_parse) + { + PKCS7 * p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); +@@ -993,16 +1026,13 @@ static LUA_FUNCTION(openssl_pkcs7_parse) + case NID_pkcs7_digest: + { + PKCS7_DIGEST* d = p7->d.digest; +- +- ASN1_OCTET_STRING *as = ASN1_STRING_dup(d->digest); +- PUSH_OBJECT(as, "openssl.asn1_string"); ++ PUSH_ASN1_OCTET_STRING(L, d->digest); + lua_setfield(L, -2, "digest"); + } + break; + case NID_pkcs7_data: + { +- ASN1_OCTET_STRING *as = ASN1_STRING_dup(p7->d.data); +- PUSH_OBJECT(as, "openssl.asn1_string"); ++ PUSH_ASN1_OCTET_STRING(L, p7->d.data); + lua_setfield(L, -2, "data"); + } + break; +@@ -1026,13 +1056,417 @@ static LUA_FUNCTION(openssl_pkcs7_parse) + return 1; + } + ++/*** ++pkcs7 sign add signer ++ ++@function add_signer ++@tparam x509 cert used to sign data ++@tparam evp_pkey pkey used to sign data ++@tparam evp_md|int digest method when sign data ++@tparam[opt=0] int flags switch process when add signer ++@treturn boolean result true for success ++*/ ++static LUA_FUNCTION(openssl_pkcs7_sign_add_signer) ++{ ++ PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); ++ X509 *signcert = CHECK_OBJECT(2, X509, "openssl.x509"); ++ EVP_PKEY *pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); ++ const EVP_MD* md = get_digest(L, 4, NULL); ++ long flags = luaL_optint(L, 5, 0); ++ PKCS7_SIGNER_INFO *signer = 0; ++ ++ luaL_argcheck(L, X509_check_private_key(signcert, pkey), 3, ++ "sigcert and private key not match"); ++ ++ signer = PKCS7_sign_add_signer(p7, signcert, pkey, md, flags); ++ (void) signer; ++ return openssl_pushresult(L, signcert != NULL ? 1 : 0); ++} ++ ++#if OPENSSL_VERSION_NUMBER > 0x10000000L ++/*** ++pkcs7 sign hash data ++@function sign_digest ++@tparam string data to sign data, maybe already hashed ++@tparam[opt=0] int flags when sign data ++@tparam[opt=false] boolean hashed when true will skip hash process ++@treturn boolean result true for success ++*/ ++static LUA_FUNCTION(openssl_pkcs7_sign_digest) ++{ ++ PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); ++ size_t l; ++ const char* data = luaL_checklstring(L, 2, &l); ++ long flags = luaL_optint(L, 3, 0); ++ int hash = lua_isnoneornil(L, 4) ? 0 : lua_toboolean(L, 4); ++ ++ int ret = 0; ++ int i, j; ++ ++ const EVP_MD* md; ++ PKCS7_SIGNER_INFO *si; ++ EVP_MD_CTX *mdc; ++ STACK_OF(X509_ATTRIBUTE) *sk; ++ STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; ++ ASN1_OCTET_STRING *os = NULL; ++ ++ if (p7->d.ptr == NULL) ++ { ++ luaL_error(L, "pkcs7 without content"); ++ return 0; ++ } ++ ++ if (flags & PKCS7_DETACHED) ++ { ++ PKCS7_set_detached(p7, 1); ++ } ++ ++ mdc = EVP_MD_CTX_new(); ++ EVP_MD_CTX_init(mdc); ++ i = OBJ_obj2nid(p7->type); ++ p7->state = PKCS7_S_HEADER; ++ ++ switch (i) ++ { ++ case NID_pkcs7_data: ++ os = p7->d.data; ++ break; ++ case NID_pkcs7_signedAndEnveloped: ++ /* XXXXXXXXXXXXXXXX */ ++ si_sk = p7->d.signed_and_enveloped->signer_info; ++ os = p7->d.signed_and_enveloped->enc_data->enc_data; ++ if (!os) ++ { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++ os = M_ASN1_OCTET_STRING_new(); ++#else ++ os = ASN1_OCTET_STRING_new(); ++#endif ++ if (!os) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ p7->d.signed_and_enveloped->enc_data->enc_data = os; ++ } ++ break; ++ case NID_pkcs7_enveloped: ++ /* XXXXXXXXXXXXXXXX */ ++ os = p7->d.enveloped->enc_data->enc_data; ++ if (!os) ++ { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++ os = M_ASN1_OCTET_STRING_new(); ++#else ++ os = ASN1_OCTET_STRING_new(); ++#endif ++ if (!os) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ p7->d.enveloped->enc_data->enc_data = os; ++ } ++ break; ++ case NID_pkcs7_signed: ++ si_sk = p7->d.sign->signer_info; ++ os = PKCS7_get_octet_string(p7->d.sign->contents); ++ /* If detached data then the content is excluded */ ++ if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) ++ { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++ M_ASN1_OCTET_STRING_free(os); ++#else ++ ASN1_OCTET_STRING_free(os); ++#endif ++ os = NULL; ++ p7->d.sign->contents->d.data = NULL; ++ } ++ break; ++ ++ case NID_pkcs7_digest: ++ os = PKCS7_get_octet_string(p7->d.digest->contents); ++ /* If detached data then the content is excluded */ ++ if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) ++ { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++ M_ASN1_OCTET_STRING_free(os); ++#else ++ ASN1_OCTET_STRING_free(os); ++#endif ++ os = NULL; ++ p7->d.digest->contents->d.data = NULL; ++ } ++ break; ++ ++ default: ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); ++ goto err; ++ } ++ ++ if (si_sk != NULL) ++ { ++ for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) ++ { ++ si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); ++ if (si->pkey == NULL) ++ continue; ++ j = OBJ_obj2nid(si->digest_alg->algorithm); ++ md = EVP_get_digestbynid(j); ++ EVP_DigestInit_ex(mdc, md, NULL); ++ ++ if (hash) ++ { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++ if (l == (size_t) mdc->digest->ctx_size) ++ { ++ memcpy(mdc->md_data, data, l); ++ } ++#else ++ if (l == (size_t)EVP_MD_meth_get_app_datasize(EVP_MD_CTX_md(mdc))) ++ { ++ memcpy(EVP_MD_CTX_md_data(mdc), data, l); ++ } ++#endif ++ else ++ { ++ EVP_MD_CTX_free(mdc); ++ luaL_argerror(L, 2, "data with wrong length"); ++ } ++ } ++ else ++ EVP_DigestUpdate(mdc, data, l); ++ ++ sk = si->auth_attr; ++ ++ /* ++ * If there are attributes, we add the digest attribute and only ++ * sign the attributes ++ */ ++ if (sk_X509_ATTRIBUTE_num(sk) > 0) ++ { ++ if (!do_pkcs7_signed_attrib(si, mdc)) ++ goto err; ++ } ++ else ++ { ++ unsigned char *abuf = NULL; ++ unsigned int abuflen; ++ abuflen = EVP_PKEY_size(si->pkey); ++ abuf = OPENSSL_malloc(abuflen); ++ if (!abuf) ++ goto err; ++ ++ if (!EVP_SignFinal(mdc, abuf, &abuflen, si->pkey)) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); ++ goto err; ++ } ++ ASN1_STRING_set0(si->enc_digest, abuf, abuflen); ++ } ++ } ++ } ++ else if (i == NID_pkcs7_digest) ++ { ++ unsigned char md_data[EVP_MAX_MD_SIZE]; ++ unsigned int md_len; ++ md = EVP_get_digestbynid(OBJ_obj2nid(p7->d.digest->md->algorithm)); ++ EVP_DigestInit_ex(mdc, md, NULL); ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++ if (l == (size_t) mdc->digest->ctx_size) ++ { ++ memcpy(mdc->md_data, data, l); ++ } ++#else ++ if (l == (size_t)EVP_MD_meth_get_app_datasize(EVP_MD_CTX_md(mdc))) ++ { ++ memcpy(EVP_MD_CTX_md_data(mdc), data, l); ++ } ++#endif ++ else ++ { ++ EVP_MD_CTX_free(mdc); ++ luaL_error(L, "data with wrong data"); ++ } ++ if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) ++ goto err; ++ ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); ++ } ++ ++ if (!PKCS7_is_detached(p7)) ++ { ++ /* ++ * NOTE(emilia): I think we only reach os == NULL here because detached ++ * digested data support is broken. ++ */ ++ if (os == NULL) ++ goto err; ++ if (!(os->flags & ASN1_STRING_FLAG_NDEF)) ++ { ++ char *cont = memdup(data, l); ++ long contlen = l; ++ ASN1_STRING_set0(os, (unsigned char *) cont, contlen); ++ } ++ } ++ ++ ret = 1; ++err: ++ EVP_MD_CTX_free(mdc); ++ return openssl_pushresult(L, ret); ++} ++ ++/*** ++pkcs7 verify signature or digest ++ ++@function verify_digest ++@tparam[opt] table certs contains certificate used to sign data ++@tparam[opt] x509_store store to verify certs ++@tparam string data to be signed ++@tparam[opt=false] boolean hashed true for data already hashed ++@treturn boolean result true for success ++*/ ++static LUA_FUNCTION(openssl_pkcs7_verify_digest) ++{ ++ PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); ++ STACK_OF(X509) *certs = lua_isnoneornil(L, 2) ? NULL : openssl_sk_x509_fromtable(L, 2); ++ X509_STORE *store = lua_isnoneornil(L, 3) ? NULL : CHECK_OBJECT(3, X509_STORE, "openssl.x509_store"); ++ size_t len = 0; ++ const char* data = luaL_optlstring(L, 4, NULL, &len); ++ long flags = luaL_optint(L, 5, 0); ++ int hash = lua_isnoneornil(L, 6) ? 0 : lua_toboolean(L, 6); ++ ++ STACK_OF(X509) *signers; ++ X509 *signer; ++ STACK_OF(PKCS7_SIGNER_INFO) *sinfos; ++ PKCS7_SIGNER_INFO *si; ++ X509_STORE_CTX *cert_ctx; ++ ++ int i, j = 0, k, ret = 0; ++ ++ /* Check for no data and no content: no data to verify signature */ ++ if (flags & PKCS7_DETACHED) ++ { ++ if (!PKCS7_get_detached(p7)) ++ { ++ luaL_error(L, "pkcs7 must be detached signedData"); ++ } ++ luaL_argcheck(L, data != NULL, 4, "need data to be verified"); ++ } ++ else ++ { ++ ASN1_OCTET_STRING *os = NULL; ++ ++ luaL_argcheck(L, data == NULL, 4, "must be nil or none"); ++ os = PKCS7_get_octet_string(p7->d.sign->contents); ++ data = (const char*)os->data; ++ len = os->length; ++ } ++ ++ sinfos = PKCS7_get_signer_info(p7); ++ if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) ++ { ++ luaL_error(L, "pkcs7 signedData without signature"); ++ } ++ ++ signers = PKCS7_get0_signers(p7, certs, flags); ++ if (!signers) ++ { ++ luaL_error(L, "pkcs7 signedData without signers"); ++ } ++ ++ if (!store) ++ flags |= PKCS7_NOVERIFY; ++ ++ /* Now verify the certificates */ ++ if (!(flags & PKCS7_NOVERIFY)) ++ for (k = 0; k < sk_X509_num(signers); k++) ++ { ++ signer = sk_X509_value(signers, k); ++ cert_ctx = X509_STORE_CTX_new(); ++ if (!(flags & PKCS7_NOCHAIN)) ++ { ++ if (!X509_STORE_CTX_init(cert_ctx, store, signer, ++ p7->d.sign->cert)) ++ { ++ PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); ++ goto err; ++ } ++ X509_STORE_CTX_set_default(cert_ctx, "smime_sign"); ++ } ++ else if (!X509_STORE_CTX_init(cert_ctx, store, signer, NULL)) ++ { ++ PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); ++ goto err; ++ } ++ if (!(flags & PKCS7_NOCRL)) ++ X509_STORE_CTX_set0_crls(cert_ctx, p7->d.sign->crl); ++ i = X509_verify_cert(cert_ctx); ++ if (i <= 0) ++ j = X509_STORE_CTX_get_error(cert_ctx); ++ X509_STORE_CTX_free(cert_ctx); ++ if (i <= 0) ++ { ++ PKCS7err(PKCS7_F_PKCS7_VERIFY, ++ PKCS7_R_CERTIFICATE_VERIFY_ERROR); ++ ERR_add_error_data(2, "Verify error:", ++ X509_verify_cert_error_string(j)); ++ goto err; ++ } ++ /* Check for revocation status here */ ++ } ++ ++ /* Now Verify All Signatures */ ++ if (!(flags & PKCS7_NOSIGS)) ++ for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) ++ { ++ si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); ++ signer = sk_X509_value(signers, i); ++ j = PKCS7_signatureVerify_digest(p7, si, signer, ++ (const unsigned char*) data, len, hash); ++ if (j <= 0) ++ { ++ PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE); ++ goto err; ++ } ++ } ++ ret = 1; ++ ++err: ++ if (certs) ++ sk_X509_pop_free(certs, X509_free); ++ sk_X509_free(signers); ++ return openssl_pushresult(L, ret); ++} ++#endif ++/*** ++verify pkcs7 object, and return msg content, follow by singers ++ ++@function verify ++@tparam[opt] stack_of_x509 signercerts ++@tparam[opt] x509_store cacerts ++@tparam[opt] string|bio msg ++@tparam[opt=0] number flags ++@treturn string content ++@treturn stack_of_x509 signers ++*/ ++ ++/*** ++decrypt encrypted pkcs7 message ++ ++@function decrypt ++@tparam x509 recipcert ++@tparam evp_pkey recipkey ++@treturn string decrypt message ++*/ ++ + static luaL_Reg pkcs7_funcs[] = + { ++ {"type", openssl_pkcs7_type}, + {"parse", openssl_pkcs7_parse}, + {"export", openssl_pkcs7_export}, + {"decrypt", openssl_pkcs7_decrypt}, + {"verify", openssl_pkcs7_verify}, +- ++ {"final", openssl_pkcs7_final}, + #if OPENSSL_VERSION_NUMBER > 0x10000000L + {"add_signer", openssl_pkcs7_sign_add_signer}, + {"add", openssl_pkcs7_add}, +@@ -1060,7 +1494,7 @@ static const luaL_Reg R[] = + {NULL, NULL} + }; + +-static LuaL_Enum pkcs7_const[] = ++static LuaL_Enumeration pkcs7_const[] = + { + {"TEXT", PKCS7_TEXT}, + {"NOCERTS", PKCS7_NOCERTS}, +@@ -1084,7 +1518,6 @@ static LuaL_Enum pkcs7_const[] = + + int luaopen_pkcs7(lua_State *L) + { +- int i; + auxiliar_newclass(L, "openssl.pkcs7", pkcs7_funcs); + + lua_newtable(L); +@@ -1094,11 +1527,6 @@ int luaopen_pkcs7(lua_State *L) + lua_pushliteral(L, MYVERSION); + lua_settable(L, -3); + +- for (i = 0; i < sizeof(pkcs7_const) / sizeof(LuaL_Enum) - 1; i++) +- { +- LuaL_Enum e = pkcs7_const[i]; +- lua_pushinteger(L, e.val); +- lua_setfield(L, -2, e.name); +- } ++ auxiliar_enumerate(L, -1, pkcs7_const); + return 1; + } +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/pkey.c luvi-src-v2.7.6/deps/lua-openssl/src/pkey.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/pkey.c 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/pkey.c 2019-02-13 11:53:24.298459641 +0100 +@@ -1,10 +1,9 @@ +-/*=========================================================================*\ +-* pkey.c +-* pkey module for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ +- ++/*** ++pkey module for lua-openssl binding ++@module pkey ++@usage ++ pkey = require'openssl'.pkey ++*/ + #include "openssl.h" + #include "private.h" + #include +@@ -16,70 +15,71 @@ + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + +-static int openssl_pkey_bits(lua_State *L) +-{ +- EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); +- lua_Integer ret = EVP_PKEY_bits(pkey); +- lua_pushinteger(L, ret); +- return 1; +-}; +- + int openssl_pkey_is_private(EVP_PKEY* pkey) + { ++ int ret = 1; ++ int typ; + assert(pkey != NULL); +- +- switch (pkey->type) ++ typ = EVP_PKEY_type(EVP_PKEY_id(pkey)); ++ switch (typ) + { + #ifndef OPENSSL_NO_RSA + case EVP_PKEY_RSA: +- case EVP_PKEY_RSA2: +- assert(pkey->pkey.rsa != NULL); +- if (pkey->pkey.rsa != NULL && (NULL == pkey->pkey.rsa->p || NULL == pkey->pkey.rsa->q)) +- { +- return 0; +- } ++ { ++ RSA *rsa = EVP_PKEY_get0_RSA(pkey); ++ const BIGNUM *d = NULL; ++ ++ RSA_get0_key(rsa, NULL, NULL, &d); ++ ret = d != NULL; + break; ++ } + #endif + #ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: +- case EVP_PKEY_DSA1: +- case EVP_PKEY_DSA2: +- case EVP_PKEY_DSA3: +- case EVP_PKEY_DSA4: +- assert(pkey->pkey.dsa != NULL); +- +- if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key) +- { +- return 0; +- } ++ { ++ DSA *dsa = EVP_PKEY_get0_DSA(pkey); ++ const BIGNUM *p = NULL; ++ DSA_get0_key(dsa, NULL, &p); ++ ret = p != NULL; + break; ++ } + #endif + #ifndef OPENSSL_NO_DH + case EVP_PKEY_DH: +- assert(pkey->pkey.dh != NULL); +- +- if (NULL == pkey->pkey.dh->p || NULL == pkey->pkey.dh->priv_key) +- { +- return 0; +- } ++ { ++ DH *dh = EVP_PKEY_get0_DH(pkey); ++ const BIGNUM *p = NULL; ++ DH_get0_key(dh, NULL, &p); ++ ret = p != NULL; + break; ++ } + #endif + #ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: +- assert(pkey->pkey.ec != NULL); +- if (NULL == EC_KEY_get0_private_key(pkey->pkey.ec)) +- { +- return 0; +- } ++ { ++ EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); ++ const BIGNUM *p = EC_KEY_get0_private_key(ec); ++ ret = p != NULL; + break; ++ } + #endif + default: +- return -1; ++ ret = 0; + break; + } +- return 1; ++ return ret; + } + ++/*** ++read public/private key from data ++@function read ++@tparam string|openssl.bio input string data or bio object ++@tparam[opt=false] boolean priv prikey set true when input is private key ++@tparam[opt='auto'] string format or encoding of input, support 'auto','pem','der' ++@tparam[opt] string passhprase when input is private key, or key types 'ec','rsa','dsa','dh' ++@treturn evp_pkey public key ++@see evp_pkey ++*/ + static int openssl_pkey_read(lua_State*L) + { + EVP_PKEY * key = NULL; +@@ -96,6 +96,8 @@ static int openssl_pkey_read(lua_State*L + type = EVP_PKEY_DSA; + else if (strcmp(passphrase, "ec") == 0 || strcmp(passphrase, "EC") == 0) + type = EVP_PKEY_EC; ++ else if (strcmp(passphrase, "dh") == 0 || strcmp(passphrase, "DH") == 0) ++ type = EVP_PKEY_DH; + } + + if (fmt == FORMAT_AUTO) +@@ -107,9 +109,9 @@ static int openssl_pkey_read(lua_State*L + { + if (fmt == FORMAT_PEM) + { +- key = PEM_read_bio_PUBKEY(in, NULL, NULL, (void*)passphrase); +- BIO_reset(in); +- if (key == NULL && type == EVP_PKEY_RSA) ++ switch (type) ++ { ++ case EVP_PKEY_RSA: + { + RSA* rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); + if (rsa) +@@ -117,21 +119,109 @@ static int openssl_pkey_read(lua_State*L + key = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(key, rsa); + } ++ break; + } ++ case EVP_PKEY_DSA: ++ { ++ DSA* dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL); ++ if (dsa) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_DSA(key, dsa); ++ } ++ break; ++ } ++ case EVP_PKEY_DH: ++ { ++ DH *dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); ++ if (dh) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_DH(key, dh); ++ } ++ break; ++ } ++ case EVP_PKEY_EC: ++ { ++ EC_KEY *ec = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL); ++ if (ec) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_EC_KEY(key, ec); ++ } ++ break; ++ } ++ default: ++ { ++ key = PEM_read_bio_PUBKEY(in, NULL, NULL, NULL); ++ break; ++ } ++ } ++ (void)BIO_reset(in); + } + else if (fmt == FORMAT_DER) + { +- key = d2i_PUBKEY_bio(in, NULL); +- BIO_reset(in); +- if (!key && type != -1) ++ switch (type) ++ { ++ case EVP_PKEY_RSA: ++ { ++ RSA *rsa = d2i_RSAPublicKey_bio(in, NULL); ++ if (rsa) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_RSA(key, rsa); ++ } ++ break; ++ } ++ case EVP_PKEY_DSA: ++ case EVP_PKEY_DH: ++ case EVP_PKEY_EC: + { + char * bio_mem_ptr; + long bio_mem_len; +- ++ const unsigned char **pp; + bio_mem_len = BIO_get_mem_data(in, &bio_mem_ptr); +- key = d2i_PublicKey(type, NULL, (const unsigned char **)&bio_mem_ptr, bio_mem_len); +- BIO_reset(in); ++ pp = (const unsigned char **)&bio_mem_ptr; ++ ++ key = d2i_PublicKey(type, NULL, pp, bio_mem_len); ++ } ++ /* ++ case EVP_PKEY_DSA: ++ { ++ DSA *dsa = d2i_DSA_PUBKEY_bio(in, NULL); ++ if (dsa) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_DSA(key, dsa); ++ } ++ break; ++ } ++ case EVP_PKEY_DH: ++ { ++ DH *dh = d2i_DHparams_bio(in, NULL); ++ if (dh) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_DH(key, dh); ++ } ++ break; ++ } ++ case EVP_PKEY_EC: ++ { ++ EC_KEY *ec = d2i_EC_PUBKEY_bio(in, NULL); ++ if (ec) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_EC_KEY(key, ec); ++ } ++ break; + } ++ */ ++ default: ++ key = d2i_PUBKEY_bio(in, NULL); ++ break; ++ } ++ (void)BIO_reset(in); + } + } + else +@@ -139,25 +229,61 @@ static int openssl_pkey_read(lua_State*L + if (fmt == FORMAT_PEM) + { + key = PEM_read_bio_PrivateKey(in, NULL, NULL, (void*)passphrase); +- BIO_reset(in); ++ (void)BIO_reset(in); + } + else if (fmt == FORMAT_DER) + { +- if (passphrase) +- key = d2i_PKCS8PrivateKey_bio(in, NULL, NULL, (void*)passphrase); +- else +- key = d2i_PrivateKey_bio(in, NULL); +- BIO_reset(in); +- +- if (!key && type != -1) ++ switch (type) + { +- char * bio_mem_ptr; +- long bio_mem_len; +- +- bio_mem_len = BIO_get_mem_data(in, &bio_mem_ptr); +- key = d2i_PrivateKey(type, NULL, (const unsigned char **)&bio_mem_ptr, bio_mem_len); +- BIO_reset(in); ++ case EVP_PKEY_RSA: ++ { ++ RSA *rsa = d2i_RSAPrivateKey_bio(in, NULL); ++ if (rsa) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_RSA(key, rsa); ++ } ++ break; + } ++ case EVP_PKEY_DSA: ++ { ++ DSA *dsa = d2i_DSAPrivateKey_bio(in, NULL); ++ if (dsa) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_DSA(key, dsa); ++ } ++ break; ++ } ++ case EVP_PKEY_DH: ++ { ++ DH *dh = d2i_DHparams_bio(in, NULL); ++ if (dh) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_DH(key, dh); ++ } ++ } ++ case EVP_PKEY_EC: ++ { ++ EC_KEY *ec = d2i_ECPrivateKey_bio(in, NULL); ++ if (ec) ++ { ++ key = EVP_PKEY_new(); ++ EVP_PKEY_assign_EC_KEY(key, ec); ++ } ++ break; ++ } ++ default: ++ { ++ if (passphrase) ++ key = d2i_PKCS8PrivateKey_bio(in, NULL, NULL, (void*)passphrase); ++ else ++ key = d2i_PrivateKey_bio(in, NULL); ++ break; ++ } ++ } ++ (void)BIO_reset(in); + } + } + BIO_free(in); +@@ -232,7 +358,7 @@ err: + size_t l = 0; const char* bn = luaL_checklstring(L, -1, &l); \ + if (_name == NULL) _name = BN_new(); \ + BN_bin2bn((const unsigned char *)bn, l, _name); \ +- } else if (auxiliar_isclass(L, "openssl.bn", -1)) { \ ++ } else if (auxiliar_getclassudata(L, "openssl.bn", -1)) { \ + const BIGNUM* bn = CHECK_OBJECT(-1, BIGNUM, "openssl.bn"); \ + if (_name == NULL) _name = BN_new(); \ + BN_copy(_name, bn); \ +@@ -241,6 +367,40 @@ err: + lua_pop(L, 1); \ + } + ++/*** ++generate a new ec keypair ++@function new ++@tparam string alg, alg must be 'ec' ++@tparam string|number curvename this can be integer as curvename NID ++@tparam[opt] integer flags when alg is ec need this. ++@treturn evp_pkey object with mapping to EVP_PKEY in openssl ++*/ ++/*** ++generate a new keypair ++@function new ++@tparam[opt='rsa'] string alg, accept `rsa`,`dsa`,`dh` ++@tparam[opt=2048|512] integer bits, `rsa` with 2048, `dh` or `dsa` with 1024 ++@tparam[opt] integer e, when alg is `rsa` give e value default is 0x10001, ++ when alg is `dh` give generator value default is 2, ++ when alg is `dsa` give string type seed value default is none. ++@tparam[opt] engine eng ++@treturn evp_pkey object with mapping to EVP_PKEY in openssl ++*/ ++/*** ++create a new keypair by factors of keypair or get public key only ++@function new ++@tparam table factors to create private/public key, key alg only accept accept 'rsa','dsa','dh','ec' and must exist
++ when arg is rsa, table may with key n,e,d,p,q,dmp1,dmq1,iqmp, both are binary string or openssl.bn
++ when arg is dsa, table may with key p,q,g,priv_key,pub_key, both are binary string or openssl.bn
++ when arg is dh, table may with key p,g,priv_key,pub_key, both are binary string or openssl.bn
++ when arg is ec, table may with D,X,Y,Z,both are binary string or openssl.bn
++@treturn evp_pkey object with mapping to EVP_PKEY in openssl ++@usage ++ --create rsa public key ++ pubkey = new({alg='rsa',n=...,e=...} ++ --create new rsa ++ rsa = new({alg='rsa',n=...,q=...,e=...,...} ++*/ + static LUA_FUNCTION(openssl_pkey_new) + { + EVP_PKEY *pkey = NULL; +@@ -252,10 +412,11 @@ static LUA_FUNCTION(openssl_pkey_new) + + if (strcasecmp(alg, "rsa") == 0) + { +- int bits = luaL_optint(L, 2, 1024); ++ int bits = luaL_optint(L, 2, 2048); + int e = luaL_optint(L, 3, 65537); +- RSA* rsa = RSA_new(); ++ ENGINE *eng = lua_isnoneornil(L, 4) ? NULL : CHECK_OBJECT(4, ENGINE, "openssl.engine"); + ++ RSA *rsa = eng ? RSA_new_method(eng) : RSA_new(); + BIGNUM *E = BN_new(); + BN_set_word(E, e); + if (RSA_generate_key_ex(rsa, bits, E, NULL)) +@@ -272,8 +433,9 @@ static LUA_FUNCTION(openssl_pkey_new) + int bits = luaL_optint(L, 2, 1024); + size_t seed_len = 0; + const char* seed = luaL_optlstring(L, 3, NULL, &seed_len); ++ ENGINE *eng = lua_isnoneornil(L, 4) ? NULL : CHECK_OBJECT(4, ENGINE, "openssl.engine"); + +- DSA *dsa = DSA_new(); ++ DSA *dsa = eng ? DSA_new_method(eng) : DSA_new(); + if (DSA_generate_parameters_ex(dsa, bits, (byte*)seed, seed_len, NULL, NULL, NULL) + && DSA_generate_key(dsa)) + { +@@ -285,10 +447,11 @@ static LUA_FUNCTION(openssl_pkey_new) + } + else if (strcasecmp(alg, "dh") == 0) + { +- int bits = luaL_optint(L, 2, 512); ++ int bits = luaL_optint(L, 2, 1024); + int generator = luaL_optint(L, 3, 2); ++ ENGINE *eng = lua_isnoneornil(L, 4) ? NULL : CHECK_OBJECT(4, ENGINE, "openssl.engine"); + +- DH* dh = DH_new(); ++ DH* dh = eng ? DH_new_method(eng) : DH_new(); + if (DH_generate_parameters_ex(dh, bits, generator, NULL)) + { + if (DH_generate_key(dh)) +@@ -324,7 +487,6 @@ static LUA_FUNCTION(openssl_pkey_new) + } + else + EC_GROUP_free(group); +- + } + #endif + else +@@ -345,22 +507,59 @@ static LUA_FUNCTION(openssl_pkey_new) + RSA *rsa = RSA_new(); + if (rsa) + { +- OPENSSL_PKEY_SET_BN(1, rsa, n); +- OPENSSL_PKEY_SET_BN(1, rsa, e); +- OPENSSL_PKEY_SET_BN(1, rsa, d); +- OPENSSL_PKEY_SET_BN(1, rsa, p); +- OPENSSL_PKEY_SET_BN(1, rsa, q); +- OPENSSL_PKEY_SET_BN(1, rsa, dmp1); +- OPENSSL_PKEY_SET_BN(1, rsa, dmq1); +- OPENSSL_PKEY_SET_BN(1, rsa, iqmp); +- if (rsa->n) ++ BIGNUM *n = NULL, *e = NULL, *d = NULL; ++ BIGNUM *p = NULL, *q = NULL; ++ BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; ++ ++ lua_getfield(L, 1, "n"); ++ n = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "e"); ++ e = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "d"); ++ d = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "p"); ++ p = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "q"); ++ q = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "dmp1"); ++ dmp1 = BN_get(L, -1); ++ lua_pop(L, 1); ++ lua_getfield(L, 1, "dmq1"); ++ dmq1 = BN_get(L, -1); ++ lua_pop(L, 1); ++ lua_getfield(L, 1, "iqmp"); ++ iqmp = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ if (RSA_set0_key(rsa, n, e, d) == 1 ++ && (p == NULL || RSA_set0_factors(rsa, p, q) == 1) ++ && (dmp1 == NULL || RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 1) ) + { + if (!EVP_PKEY_assign_RSA(pkey, rsa)) + { ++ RSA_free(rsa); ++ rsa = NULL; + EVP_PKEY_free(pkey); + pkey = NULL; + } + } ++ else ++ { ++ RSA_free(rsa); ++ rsa = NULL; ++ EVP_PKEY_free(pkey); ++ pkey = NULL; ++ } + } + } + } +@@ -372,23 +571,46 @@ static LUA_FUNCTION(openssl_pkey_new) + DSA *dsa = DSA_new(); + if (dsa) + { +- OPENSSL_PKEY_SET_BN(-1, dsa, p); +- OPENSSL_PKEY_SET_BN(-1, dsa, q); +- OPENSSL_PKEY_SET_BN(-1, dsa, g); +- OPENSSL_PKEY_SET_BN(-1, dsa, priv_key); +- OPENSSL_PKEY_SET_BN(-1, dsa, pub_key); +- if (dsa->p && dsa->q && dsa->g) ++ BIGNUM *p = NULL, *q = NULL, *g = NULL; ++ BIGNUM *priv_key = NULL, *pub_key = NULL; ++ ++ lua_getfield(L, 1, "p"); ++ p = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "q"); ++ q = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "g"); ++ g = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "priv_key"); ++ priv_key = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "pub_key"); ++ pub_key = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ if (DSA_set0_key(dsa, pub_key, priv_key) == 1 ++ && DSA_set0_pqg(dsa, p, q, g)) + { +- if (!dsa->priv_key && !dsa->pub_key) +- { +- DSA_generate_key(dsa); +- } + if (!EVP_PKEY_assign_DSA(pkey, dsa)) + { ++ DSA_free(dsa); + EVP_PKEY_free(pkey); + pkey = NULL; + } + } ++ else ++ { ++ DSA_free(dsa); ++ dsa = NULL; ++ EVP_PKEY_free(pkey); ++ pkey = NULL; ++ } + } + } + } +@@ -401,22 +623,47 @@ static LUA_FUNCTION(openssl_pkey_new) + DH *dh = DH_new(); + if (dh) + { +- OPENSSL_PKEY_SET_BN(-1, dh, p); +- OPENSSL_PKEY_SET_BN(-1, dh, g); +- OPENSSL_PKEY_SET_BN(-1, dh, priv_key); +- OPENSSL_PKEY_SET_BN(-1, dh, pub_key); +- if (dh->p && dh->g) ++ BIGNUM *p = NULL, *q = NULL, *g = NULL; ++ BIGNUM *priv_key = NULL, *pub_key = NULL; ++ ++ lua_getfield(L, 1, "p"); ++ p = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "q"); ++ q = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "g"); ++ g = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "priv_key"); ++ priv_key = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ lua_getfield(L, 1, "pub_key"); ++ pub_key = BN_get(L, -1); ++ lua_pop(L, 1); ++ ++ if (DH_set0_key(dh, pub_key, priv_key) == 1 ++ && DH_set0_pqg(dh, p, q, g)) + { +- if (!dh->pub_key) +- { +- DH_generate_key(dh); +- } + if (!EVP_PKEY_assign_DH(pkey, dh)) + { ++ DH_free(dh); ++ dh = NULL; + EVP_PKEY_free(pkey); + pkey = NULL; + } + } ++ else ++ { ++ DH_free(dh); ++ dh = NULL; ++ EVP_PKEY_free(pkey); ++ pkey = NULL; ++ } + } + } + } +@@ -482,8 +729,14 @@ static LUA_FUNCTION(openssl_pkey_new) + EC_GROUP_free(group); + } + } ++ else if (auxiliar_getclassudata(L, "openssl.rsa", 1)) ++ { ++ RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); ++ pkey = EVP_PKEY_new(); ++ EVP_PKEY_assign_RSA(pkey, rsa); ++ } + +- if (pkey && pkey->pkey.ptr) ++ if (pkey && EVP_PKEY_id(pkey) != NID_undef) + { + PUSH_OBJECT(pkey, "openssl.evp_pkey"); + return 1; +@@ -491,15 +744,27 @@ static LUA_FUNCTION(openssl_pkey_new) + else + EVP_PKEY_free(pkey); + return 0; +- + } + ++/*** ++openssl.evp_pkey object ++@type evp_pkey ++*/ ++/*** ++export evp_pkey as pem/der string ++@function export ++@tparam[opt='pem'] string support export as 'pem' or 'der' format, default is 'pem' ++@tparam[opt=false] boolean raw true for export low layer key just rsa,dsa,ec ++@tparam[opt] string passphrase if given, export key will encrypt with des-cbc-ede, ++only need when export private key ++@treturn string ++*/ + static LUA_FUNCTION(openssl_pkey_export) + { + EVP_PKEY * key; + int ispriv = 0; + int exraw = 0; +- int expem = 1; ++ int fmt = FORMAT_AUTO; + size_t passphrase_len = 0; + BIO * bio_out = NULL; + int ret = 0; +@@ -509,19 +774,16 @@ static LUA_FUNCTION(openssl_pkey_export) + key = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); + ispriv = openssl_pkey_is_private(key); + +- if (!lua_isnoneornil(L, 2)) +- expem = lua_toboolean(L, 2); +- +- if (expem) +- { +- if (!lua_isnoneornil(L, 3)) +- exraw = lua_toboolean(L, 3); +- passphrase = luaL_optlstring(L, 4, NULL, &passphrase_len); +- } +- else +- { +- passphrase = luaL_optlstring(L, 3, NULL, &passphrase_len); +- } ++ fmt = lua_type(L, 2); ++ luaL_argcheck(L, fmt == LUA_TSTRING || fmt == LUA_TNONE, 2, ++ "only accept 'pem','der' or none"); ++ fmt = luaL_checkoption(L, 2, "pem", format); ++ luaL_argcheck(L, fmt == FORMAT_PEM || fmt == FORMAT_DER, 2, ++ "only accept pem or der, default is pem"); ++ ++ if (!lua_isnoneornil(L, 3)) ++ exraw = lua_toboolean(L, 3); ++ passphrase = luaL_optlstring(L, 4, NULL, &passphrase_len); + + if (passphrase) + { +@@ -533,7 +795,7 @@ static LUA_FUNCTION(openssl_pkey_export) + } + + bio_out = BIO_new(BIO_s_mem()); +- if (expem) ++ if (fmt == FORMAT_PEM) + { + if (exraw == 0) + { +@@ -544,29 +806,25 @@ static LUA_FUNCTION(openssl_pkey_export) + else + { + /* export raw key format */ +- switch (EVP_PKEY_type(key->type)) ++ switch (EVP_PKEY_type(EVP_PKEY_id(key))) + { + case EVP_PKEY_RSA: +- case EVP_PKEY_RSA2: +- ret = ispriv ? PEM_write_bio_RSAPrivateKey(bio_out, key->pkey.rsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) +- : PEM_write_bio_RSAPublicKey(bio_out, key->pkey.rsa); ++ ret = ispriv ? PEM_write_bio_RSAPrivateKey(bio_out, EVP_PKEY_get0_RSA(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) ++ : PEM_write_bio_RSAPublicKey(bio_out, EVP_PKEY_get0_RSA(key)); + break; + case EVP_PKEY_DSA: +- case EVP_PKEY_DSA2: +- case EVP_PKEY_DSA3: +- case EVP_PKEY_DSA4: + { +- ret = ispriv ? PEM_write_bio_DSAPrivateKey(bio_out, key->pkey.dsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) +- : PEM_write_bio_DSA_PUBKEY(bio_out, key->pkey.dsa); ++ ret = ispriv ? PEM_write_bio_DSAPrivateKey(bio_out, EVP_PKEY_get0_DSA(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) ++ : PEM_write_bio_DSA_PUBKEY(bio_out, EVP_PKEY_get0_DSA(key)); + } + break; + case EVP_PKEY_DH: +- ret = PEM_write_bio_DHparams(bio_out, key->pkey.dh); ++ ret = PEM_write_bio_DHparams(bio_out, EVP_PKEY_get0_DH(key)); + break; + #ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: +- ret = ispriv ? PEM_write_bio_ECPrivateKey(bio_out, key->pkey.ec, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) +- : PEM_write_bio_EC_PUBKEY(bio_out, key->pkey.ec); ++ ret = ispriv ? PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get0_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) ++ : PEM_write_bio_EC_PUBKEY(bio_out, EVP_PKEY_get0_EC_KEY(key)); + break; + #endif + default: +@@ -577,41 +835,45 @@ static LUA_FUNCTION(openssl_pkey_export) + } + else + { +- if (ispriv) ++ /* out put der */ ++ if (exraw == 0) + { +- if (passphrase == NULL) +- { +- ret = i2d_PrivateKey_bio(bio_out, key); +- } +- else +- { +- ret = i2d_PKCS8PrivateKey_bio(bio_out, key, cipher, (char *)passphrase, passphrase_len, NULL, NULL); +- } ++ ret = ispriv ? ++ (passphrase == NULL ? i2d_PrivateKey_bio(bio_out, key) : ++ i2d_PKCS8PrivateKey_bio(bio_out, key, cipher, (char *)passphrase, passphrase_len, NULL, NULL)) ++ : i2d_PUBKEY_bio(bio_out, key); + } + else + { +- int l; +- l = i2d_PublicKey(key, NULL); +- if (l > 0) +- { +- unsigned char* p = malloc(l); +- unsigned char* pp = p; +- l = i2d_PublicKey(key, &pp); +- if (l > 0) +- { +- BIO_write(bio_out, p, l); +- ret = 1; +- } +- else +- ret = 0; +- free(p); ++ /* output raw key, rsa, ec, dh, dsa */ ++ switch (EVP_PKEY_type(EVP_PKEY_id(key))) ++ { ++ case EVP_PKEY_RSA: ++ ret = ispriv ? i2d_RSAPrivateKey_bio(bio_out, EVP_PKEY_get0_RSA(key)) ++ : i2d_RSAPublicKey_bio(bio_out, EVP_PKEY_get0_RSA(key)); ++ break; ++ case EVP_PKEY_DSA: ++ { ++ ret = ispriv ? i2d_DSAPrivateKey_bio(bio_out, EVP_PKEY_get0_DSA(key)) ++ : i2d_DSA_PUBKEY_bio(bio_out, EVP_PKEY_get0_DSA(key)); + } +- else ++ break; ++ case EVP_PKEY_DH: ++ ret = i2d_DHparams_bio(bio_out, EVP_PKEY_get0_DH(key)); ++ break; ++#ifndef OPENSSL_NO_EC ++ case EVP_PKEY_EC: ++ ret = ispriv ? i2d_ECPrivateKey_bio(bio_out, EVP_PKEY_get0_EC_KEY(key)) ++ : i2d_EC_PUBKEY_bio(bio_out, EVP_PKEY_get0_EC_KEY(key)); ++ break; ++#endif ++ default: + ret = 0; ++ break; ++ } + } + } + +- + if (ret) + { + char * bio_mem_ptr; +@@ -637,20 +899,24 @@ static LUA_FUNCTION(openssl_pkey_free) + return 0; + } + ++/*** ++get key details as table ++@function parse ++@treturn table infos with key bits,pkey,type, pkey may be rsa,dh,dsa, show as table with factor hex encoded bignum ++*/ + static LUA_FUNCTION(openssl_pkey_parse) + { + EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); +- if (pkey->pkey.ptr) ++ if (EVP_PKEY_id(pkey) != NID_undef) + { + lua_newtable(L); + + AUXILIAR_SET(L, -1, "bits", EVP_PKEY_bits(pkey), integer); + AUXILIAR_SET(L, -1, "size", EVP_PKEY_size(pkey), integer); + +- switch (EVP_PKEY_type(pkey->type)) ++ switch (EVP_PKEY_type(EVP_PKEY_id(pkey))) + { + case EVP_PKEY_RSA: +- case EVP_PKEY_RSA2: + { + RSA* rsa = EVP_PKEY_get1_RSA(pkey); + PUSH_OBJECT(rsa, "openssl.rsa"); +@@ -661,9 +927,6 @@ static LUA_FUNCTION(openssl_pkey_parse) + + break; + case EVP_PKEY_DSA: +- case EVP_PKEY_DSA2: +- case EVP_PKEY_DSA3: +- case EVP_PKEY_DSA4: + { + DSA* dsa = EVP_PKEY_get1_DSA(pkey); + PUSH_OBJECT(dsa, "openssl.dsa"); +@@ -703,104 +966,115 @@ static LUA_FUNCTION(openssl_pkey_parse) + luaL_argerror(L, 1, "not assign any keypair"); + return 0; + }; +-/* }}} */ + ++/*** ++encrypt message with public key ++encrypt length of message must not longer than key size, if shorter will do padding,currently supports 6 padding modes. ++They are: pkcs1, sslv23, no, oaep, x931, pss. ++@function encrypt ++@tparam string data data to be encrypted ++@tparam string[opt='pkcs1'] string padding padding mode ++@treturn string encrypted message ++*/ + static LUA_FUNCTION(openssl_pkey_encrypt) + { + size_t dlen = 0; + EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); + const char *data = luaL_checklstring(L, 2, &dlen); + int padding = openssl_get_padding(L, 3, "pkcs1"); ++ ENGINE *engine = lua_isnoneornil(L, 4) ? NULL : CHECK_OBJECT(4, ENGINE, "openssl.engine"); + size_t clen = EVP_PKEY_size(pkey); + EVP_PKEY_CTX *ctx = NULL; + int ret = 0; ++ int typ = EVP_PKEY_type(EVP_PKEY_id(pkey)); + +- if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA2) ++ if (typ != EVP_PKEY_RSA && typ != EVP_PKEY_RSA2) + { + luaL_argerror(L, 2, "EVP_PKEY must be of type RSA or RSA2"); + return ret; + } + +- if (openssl_pkey_is_private(pkey) == 0) ++ ctx = EVP_PKEY_CTX_new(pkey, engine); ++ if (EVP_PKEY_encrypt_init(ctx) == 1) + { +- ctx = EVP_PKEY_CTX_new(pkey, pkey->engine); +- if (EVP_PKEY_encrypt_init(ctx) == 1) ++ if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 1) + { +- if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 1) ++ byte* buf = malloc(clen); ++ if (EVP_PKEY_encrypt(ctx, buf, &clen, (const unsigned char*)data, dlen) == 1) + { +- byte* buf = malloc(clen); +- if (EVP_PKEY_encrypt(ctx, buf, &clen, (const unsigned char*)data, dlen) == 1) +- { +- lua_pushlstring(L, (const char*)buf, clen); +- ret = 1; +- } +- else +- ret = openssl_pushresult(L, 0); +- free(buf); ++ lua_pushlstring(L, (const char*)buf, clen); ++ ret = 1; + } + else + ret = openssl_pushresult(L, 0); ++ free(buf); + } + else + ret = openssl_pushresult(L, 0); +- EVP_PKEY_CTX_free(ctx); + } + else +- { +- luaL_argerror(L, 2, "EVP_PKEY must be public key"); +- } ++ ret = openssl_pushresult(L, 0); ++ EVP_PKEY_CTX_free(ctx); + + return ret; + } + ++/*** ++decrypt message with private key ++pair with encrypt ++@function decrypt ++@tparam string data data to be decrypted ++@tparam string[opt='pkcs1'] string padding padding mode ++@treturn[1] string result ++@treturn[2] nil ++*/ + static LUA_FUNCTION(openssl_pkey_decrypt) + { + size_t dlen = 0; + EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); + const char *data = luaL_checklstring(L, 2, &dlen); + int padding = openssl_get_padding(L, 3, "pkcs1"); ++ ENGINE *engine = lua_isnoneornil(L, 4) ? NULL : CHECK_OBJECT(4, ENGINE, "openssl.engine"); + size_t clen = EVP_PKEY_size(pkey); + EVP_PKEY_CTX *ctx = NULL; + int ret = 0; ++ int type = EVP_PKEY_type(EVP_PKEY_id(pkey)); + +- if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA2) ++ if (type != EVP_PKEY_RSA && type != EVP_PKEY_RSA2) + { + luaL_argerror(L, 2, "EVP_PKEY must be of type RSA or RSA2"); + return ret; + } +- +- if (openssl_pkey_is_private(pkey)) ++ ctx = EVP_PKEY_CTX_new(pkey, engine); ++ if (EVP_PKEY_decrypt_init(ctx) == 1) + { +- ctx = EVP_PKEY_CTX_new(pkey, pkey->engine); +- if (EVP_PKEY_decrypt_init(ctx) == 1) ++ if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 1) + { +- if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 1) +- { +- byte* buf = malloc(clen); ++ byte* buf = malloc(clen); + +- if (EVP_PKEY_decrypt(ctx, buf, &clen, (const unsigned char*)data, dlen) == 1) +- { +- lua_pushlstring(L, (const char*)buf, clen); +- ret = 1; +- } +- else +- ret = openssl_pushresult(L, 0); +- free(buf); ++ if (EVP_PKEY_decrypt(ctx, buf, &clen, (const unsigned char*)data, dlen) == 1) ++ { ++ lua_pushlstring(L, (const char*)buf, clen); ++ ret = 1; + } + else + ret = openssl_pushresult(L, 0); ++ free(buf); + } + else + ret = openssl_pushresult(L, 0); +- EVP_PKEY_CTX_free(ctx); + } + else +- { +- luaL_argerror(L, 2, "EVP_PKEY must be private key"); +- } ++ ret = openssl_pushresult(L, 0); ++ EVP_PKEY_CTX_free(ctx); + return ret; + } + ++/*** ++return key is private or public ++@function is_private ++@treturn boolean ture is private or public key ++*/ + LUA_FUNCTION(openssl_pkey_is_private1) + { + EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); +@@ -813,35 +1087,37 @@ LUA_FUNCTION(openssl_pkey_is_private1) + luaL_error(L, "openssl.evp_pkey is not support"); + return 1; + } +- ++/* private usage, and for sm2 */ ++/*** ++return public key ++@function get_public ++@treturn evp_pkey pub ++*/ + static LUA_FUNCTION(openssl_pkey_get_public) + { + EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); +- int private = openssl_pkey_is_private(pkey); + int ret = 0; +- if (private == 0) +- luaL_argerror(L, 1, "alreay public key"); +- else ++ BIO* bio = BIO_new(BIO_s_mem()); ++ if (i2d_PUBKEY_bio(bio, pkey)) + { +- BIO* bio = BIO_new(BIO_s_mem()); +- if (i2d_PUBKEY_bio(bio, pkey)) +- { +- EVP_PKEY *pub = d2i_PUBKEY_bio(bio, NULL); +- PUSH_OBJECT(pub, "openssl.evp_pkey"); +- ret = 1; +- } +- BIO_free(bio); ++ EVP_PKEY *pub = d2i_PUBKEY_bio(bio, NULL); ++ PUSH_OBJECT(pub, "openssl.evp_pkey"); ++ ret = 1; + } ++ BIO_free(bio); + return ret; + } + ++/* private useage, and for sm2 */ + static LUA_FUNCTION(openssl_ec_userId) + { + EVP_PKEY* pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); + ENGINE* engine = CHECK_OBJECT(2, ENGINE, "openssl.engine"); ++ EC_KEY *ec = NULL; + + int ret = 0; +- if (!pkey || EVP_PKEY_type(pkey->type) != EVP_PKEY_EC || !pkey->pkey.ec) ++ if (!pkey || EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_EC ++ || (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL ) + { + luaL_argerror(L, 1, "only support EC key"); + } +@@ -851,7 +1127,7 @@ static LUA_FUNCTION(openssl_ec_userId) + if (lua_gettop(L) == 2) + { + ASN1_OCTET_STRING *s = ASN1_OCTET_STRING_new(); +- ret = ENGINE_ctrl(engine, 0x474554, 0x4944, pkey->pkey.ec, (void(*)(void))s); ++ ret = ENGINE_ctrl(engine, 0x474554, 0x4944, ec, (void(*)(void))s); + if (ret == 1) + lua_pushlstring(L, (const char*) ASN1_STRING_data(s), ASN1_STRING_length(s)); + else +@@ -864,11 +1140,19 @@ static LUA_FUNCTION(openssl_ec_userId) + size_t l; + const char* data = luaL_checklstring(L, 3, &l); + ASN1_OCTET_STRING_set(s, (const unsigned char*) data, l); +- ret = ENGINE_ctrl(engine, 0x534554, 0x4944, pkey->pkey.ec, (void(*)(void))s); ++ ret = ENGINE_ctrl(engine, 0x534554, 0x4944, ec, (void(*)(void))s); + return openssl_pushresult(L, ret); + } + } + ++/*** ++compute dh key, check whether then supplied key is a private key ++by checking then prime factors whether set ++@function compute_key ++@tparam string remote_public_key ++@treturn string ++@todo: more check ++*/ + static LUA_FUNCTION(openssl_dh_compute_key) + { + BIGNUM *pub; +@@ -879,16 +1163,18 @@ static LUA_FUNCTION(openssl_dh_compute_k + EVP_PKEY* pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); + size_t pub_len; + const char* pub_str = luaL_checklstring(L, 2, &pub_len); ++ DH *dh = NULL; + +- if (!pkey || EVP_PKEY_type(pkey->type) != EVP_PKEY_DH || !pkey->pkey.dh) ++ if (!pkey || EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_DH ++ || (dh = EVP_PKEY_get0_DH(pkey)) == NULL) + { + luaL_argerror(L, 1, "only support DH private key"); + } + + pub = BN_bin2bn((unsigned char*)pub_str, pub_len, NULL); + +- data = malloc(DH_size(pkey->pkey.dh) + 1); +- len = DH_compute_key((unsigned char*)data, pub, pkey->pkey.dh); ++ data = malloc(DH_size(dh) + 1); ++ len = DH_compute_key((unsigned char*)data, pub, dh); + + if (len >= 0) + { +@@ -906,78 +1192,109 @@ static LUA_FUNCTION(openssl_dh_compute_k + return ret; + } + ++/*** ++sign message with private key ++@function sign ++@tparam string data data be signed ++@tparam[opt='SHA1'] string|env_digest md_alg default use sha-1 ++@treturn string signed message ++*/ + static LUA_FUNCTION(openssl_sign) + { + size_t data_len; + EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); + const char * data = luaL_checklstring(L, 2, &data_len); +- int top = lua_gettop(L); ++ int ret = 0; ++ EVP_MD_CTX *ctx = NULL; + +- const EVP_MD *mdtype = NULL; +- if (top > 2) +- { +- mdtype = get_digest(L, 3); +- } +- else +- mdtype = EVP_get_digestbyname("sha1"); +- if (mdtype) ++ const EVP_MD *md = get_digest(L, 3, "sha256"); ++ ctx = EVP_MD_CTX_create(); ++ ret = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey); ++ if (ret == 1) + { +- int ret = 0; +- EVP_MD_CTX md_ctx; +- unsigned int siglen = EVP_PKEY_size(pkey); +- unsigned char *sigbuf = malloc(siglen + 1); +- +- EVP_SignInit(&md_ctx, mdtype); +- EVP_SignUpdate(&md_ctx, data, data_len); +- if (EVP_SignFinal (&md_ctx, sigbuf, &siglen, pkey)) ++ ret = EVP_DigestSignUpdate(ctx, data, data_len); ++ if (ret == 1) + { +- lua_pushlstring(L, (char *)sigbuf, siglen); +- ret = 1; ++ size_t siglen = 0; ++ unsigned char *sigbuf = NULL; ++ ret = EVP_DigestSignFinal(ctx, NULL, &siglen); ++ if (ret == 1) ++ { ++ siglen += 2; ++ sigbuf = OPENSSL_malloc(siglen); ++ ret = EVP_DigestSignFinal(ctx, sigbuf, &siglen); ++ if (ret == 1) ++ { ++ lua_pushlstring(L, (char *)sigbuf, siglen); ++ } ++ else ++ ret = openssl_pushresult(L, ret); ++ OPENSSL_free(sigbuf); ++ } ++ else ++ ret = openssl_pushresult(L, ret); + } +- free(sigbuf); +- EVP_MD_CTX_cleanup(&md_ctx); +- return ret; ++ else ++ ret = openssl_pushresult(L, ret); + } + else +- luaL_argerror(L, 3, "Not support digest alg"); ++ ret = openssl_pushresult(L, ret); + +- return 0; ++ EVP_MD_CTX_destroy(ctx); ++ return ret; + } + ++/*** ++verify signed message with public key ++@function verify ++@tparam string data data be signed ++@tparam string signature signed result ++@tparam[opt='SHA1'] string|env_digest md_alg default use sha-1 ++@treturn boolean true for pass verify ++*/ + static LUA_FUNCTION(openssl_verify) + { + size_t data_len, signature_len; + EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); + const char* data = luaL_checklstring(L, 2, &data_len); + const char* signature = luaL_checklstring(L, 3, &signature_len); ++ const EVP_MD *md = get_digest(L, 4, "sha256"); ++ EVP_MD_CTX *ctx = EVP_MD_CTX_create(); + +- const EVP_MD *mdtype = NULL; +- int top = lua_gettop(L); +- if (top > 3) +- { +- mdtype = get_digest(L, 4); +- } +- else +- mdtype = EVP_get_digestbyname("sha1"); +- if (mdtype) ++ int ret = EVP_DigestVerifyInit(ctx, NULL, md, NULL, pkey); ++ if (ret == 1) + { +- int result; +- EVP_MD_CTX md_ctx; +- +- EVP_VerifyInit (&md_ctx, mdtype); +- EVP_VerifyUpdate (&md_ctx, data, data_len); +- result = EVP_VerifyFinal (&md_ctx, (unsigned char *)signature, signature_len, pkey); +- EVP_MD_CTX_cleanup(&md_ctx); +- lua_pushboolean(L, result == 1); +- +- return 1; ++ ret = EVP_DigestVerifyUpdate(ctx, data, data_len); ++ if (ret == 1) ++ { ++ ret = EVP_DigestVerifyFinal(ctx, (unsigned char *)signature, signature_len); ++ if (ret == 1) ++ { ++ lua_pushboolean(L, ret == 1); ++ } ++ else ++ ret = openssl_pushresult(L, ret); ++ } ++ else ++ ret = openssl_pushresult(L, ret); + } + else +- luaL_argerror(L, 4, "Not support digest alg"); ++ ret = openssl_pushresult(L, ret); + +- return 0; ++ EVP_MD_CTX_destroy(ctx); ++ return ret; + } + ++/*** ++seal and encrypt message with one public key ++data be encrypt with secret key, secret key be encrypt with public key ++@function seal ++@tparam string data data to be encrypted ++@tparam[opt='RC4'] cipher|string alg ++@treturn string data encrypted ++@treturn string skey secret key encrypted by public key ++@treturn string iv ++*/ + static LUA_FUNCTION(openssl_seal) + { + size_t data_len; +@@ -993,7 +1310,7 @@ static LUA_FUNCTION(openssl_seal) + luaL_argerror(L, 1, "empty array"); + } + } +- else if (auxiliar_isclass(L, "openssl.evp_pkey", 1)) ++ else if (auxiliar_getclassudata(L, "openssl.evp_pkey", 1)) + { + nkeys = 1; + } +@@ -1006,7 +1323,7 @@ static LUA_FUNCTION(openssl_seal) + + if (cipher) + { +- EVP_CIPHER_CTX ctx; ++ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + int ret = 0; + EVP_PKEY **pkeys; + unsigned char **eks; +@@ -1046,20 +1363,20 @@ static LUA_FUNCTION(openssl_seal) + eksl[0] = EVP_PKEY_size(pkeys[0]); + eks[0] = malloc(eksl[0]); + } +- EVP_CIPHER_CTX_init(&ctx); ++ EVP_CIPHER_CTX_init(ctx); + + /* allocate one byte extra to make room for \0 */ + len1 = data_len + EVP_CIPHER_block_size(cipher) + 1; + buf = malloc(len1); + + +- if (!EVP_SealInit(&ctx, cipher, eks, eksl, (unsigned char*) iv, pkeys, nkeys) +- || !EVP_SealUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) ++ if (!EVP_SealInit(ctx, cipher, eks, eksl, (unsigned char*) iv, pkeys, nkeys) ++ || !EVP_SealUpdate(ctx, buf, &len1, (unsigned char *)data, data_len)) + { + luaL_error(L, "EVP_SealInit failed"); + } + +- EVP_SealFinal(&ctx, buf + len1, &len2); ++ EVP_SealFinal(ctx, buf + len1, &len2); + + if (len1 + len2 > 0) + { +@@ -1079,7 +1396,7 @@ static LUA_FUNCTION(openssl_seal) + lua_pushlstring(L, (const char*)eks[0], eksl[0]); + free(eks[0]); + } +- lua_pushlstring(L, iv, EVP_CIPHER_CTX_iv_length(&ctx)); ++ lua_pushlstring(L, iv, EVP_CIPHER_CTX_iv_length(ctx)); + + ret = 3; + } +@@ -1088,7 +1405,7 @@ static LUA_FUNCTION(openssl_seal) + free(eks); + free(eksl); + free(pkeys); +- EVP_CIPHER_CTX_cleanup(&ctx); ++ EVP_CIPHER_CTX_free(ctx); + return ret; + } + else +@@ -1096,6 +1413,62 @@ static LUA_FUNCTION(openssl_seal) + return 0; + } + ++/*** ++open and ecrypted seal data with private key ++@function open ++@tparam string ekey encrypted secret key ++@tparam string string iv ++@tparam[opt='RC4'] evp_cipher|string md_alg ++@treturn string data decrypted message or nil on failure ++*/ ++static LUA_FUNCTION(openssl_open) ++{ ++ EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); ++ size_t data_len, ekey_len, iv_len; ++ const char *data = luaL_checklstring(L, 2, &data_len); ++ const char *ekey = luaL_checklstring(L, 3, &ekey_len); ++ const char *iv = luaL_checklstring(L, 4, &iv_len); ++ ++ int ret = 0; ++ int len1, len2 = 0; ++ unsigned char *buf; ++ ++ const EVP_CIPHER *cipher = NULL; ++ ++ cipher = get_cipher(L, 5, "rc4"); ++ ++ if (cipher) ++ { ++ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); ++ len1 = data_len + 1; ++ buf = malloc(len1); ++ ++ EVP_CIPHER_CTX_init(ctx); ++ if (EVP_OpenInit(ctx, cipher, (unsigned char *)ekey, ekey_len, (const unsigned char *)iv, pkey) ++ && EVP_OpenUpdate(ctx, buf, &len1, (unsigned char *)data, data_len)) ++ { ++ len2 = data_len - len1; ++ if (!EVP_OpenFinal(ctx, buf + len1, &len2) || (len1 + len2 == 0)) ++ { ++ luaL_error(L, "EVP_OpenFinal() failed."); ++ ret = 0; ++ } ++ } ++ else ++ { ++ luaL_error(L, "EVP_OpenInit() failed."); ++ ret = 0; ++ } ++ EVP_CIPHER_CTX_free(ctx); ++ lua_pushlstring(L, (const char*)buf, len1 + len2); ++ free(buf); ++ ret = 1; ++ } ++ else ++ luaL_argerror(L, 5, "Not support cipher alg"); ++ ++ return ret; ++} + + static LUA_FUNCTION(openssl_seal_init) + { +@@ -1110,7 +1483,7 @@ static LUA_FUNCTION(openssl_seal_init) + luaL_argerror(L, 1, "empty array"); + } + } +- else if (auxiliar_isclass(L, "openssl.evp_pkey", 1)) ++ else if (auxiliar_getclassudata(L, "openssl.evp_pkey", 1)) + { + nkeys = 1; + } +@@ -1133,7 +1506,6 @@ static LUA_FUNCTION(openssl_seal_init) + eksl = malloc(nkeys * sizeof(*eksl)); + eks = malloc(nkeys * sizeof(*eks)); + +- + memset(eks, 0, sizeof(*eks) * nkeys); + + /* get the public keys we are using to seal this data */ +@@ -1235,55 +1607,6 @@ static LUA_FUNCTION(openssl_seal_final) + return 1; + } + +-static LUA_FUNCTION(openssl_open) +-{ +- EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); +- size_t data_len, ekey_len, iv_len; +- const char *data = luaL_checklstring(L, 2, &data_len); +- const char *ekey = luaL_checklstring(L, 3, &ekey_len); +- const char *iv = luaL_checklstring(L, 4, &iv_len); +- +- int ret = 0; +- int len1, len2 = 0; +- unsigned char *buf; +- +- EVP_CIPHER_CTX ctx; +- const EVP_CIPHER *cipher = NULL; +- +- cipher = get_cipher(L, 5, "rc4"); +- +- if (cipher) +- { +- len1 = data_len + 1; +- buf = malloc(len1); +- +- EVP_CIPHER_CTX_init(&ctx); +- if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, (const unsigned char *)iv, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) +- { +- len2 = data_len - len1; +- if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) +- { +- luaL_error(L, "EVP_OpenFinal() failed."); +- ret = 0; +- } +- } +- else +- { +- luaL_error(L, "EVP_OpenInit() failed."); +- ret = 0; +- } +- EVP_CIPHER_CTX_cleanup(&ctx); +- lua_pushlstring(L, (const char*)buf, len1 + len2); +- free(buf); +- ret = 1; +- } +- else +- luaL_argerror(L, 5, "Not support cipher alg"); +- +- return ret; +-} +- +- + static LUA_FUNCTION(openssl_open_init) + { + EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); +@@ -1349,6 +1672,14 @@ static LUA_FUNCTION(openssl_open_final) + return ret == 1 ? ret : openssl_pushresult(L, ret); + } + ++static int openssl_pkey_bits(lua_State *L) ++{ ++ EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); ++ lua_Integer ret = EVP_PKEY_bits(pkey); ++ lua_pushinteger(L, ret); ++ return 1; ++}; ++ + static luaL_Reg pkey_funcs[] = + { + {"is_private", openssl_pkey_is_private1}, +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/private.h luvi-src-v2.7.6/deps/lua-openssl/src/private.h +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/private.h 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/private.h 2019-02-13 11:53:24.298459641 +0100 +@@ -1,6 +1,16 @@ +-#include "openssl.h" ++#ifndef OPENSSL_PRIVATE_H ++#define OPENSSL_PRIVATE_H ++ ++#if defined(__cplusplus) ++extern "C" { ++#endif ++#include ++#include ++#include + +-#include "lua-compat/c-api/compat-5.3.h" ++#if LUA_VERSION_NUM < 503 ++#include "c-api/compat-5.3.h" ++#endif + + #define luaL_checktable(L, n) luaL_checktype(L, n, LUA_TTABLE) + +@@ -29,6 +39,110 @@ + #endif + #endif + ++#include "openssl.h" ++ ++#if OPENSSL_VERSION_NUMBER > 0x10100000L ++#define CONSTIFY_X509_get0 const ++#else ++#define CONSTIFY_X509_get0 ++#endif ++ ++#define PUSH_BN(x) \ ++ *(void **)(lua_newuserdata(L, sizeof(void *))) = (x); \ ++ luaL_getmetatable(L,"openssl.bn"); \ ++ lua_setmetatable(L,-2) ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++int BIO_up_ref(BIO *b); ++int X509_up_ref(X509 *x); ++int X509_STORE_up_ref(X509_STORE *s); ++int EVP_PKEY_up_ref(EVP_PKEY *pkey); ++ ++DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey); ++int DH_bits(const DH *dh); ++void DH_get0_key(const DH *dh, ++ const BIGNUM **pub_key, const BIGNUM **priv_key); ++int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); ++void DH_get0_pqg(const DH *dh, ++ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); ++int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); ++void DSA_get0_pqg(const DSA *dsa, ++ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); ++ ++EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); ++void ECDSA_SIG_get0(const ECDSA_SIG *sig, ++ const BIGNUM **pr, const BIGNUM **ps); ++int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); ++int RSA_bits(const RSA *r); ++void RSA_get0_key(const RSA *r, ++ const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); ++int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); ++int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); ++int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); ++void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); ++void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp); ++RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); ++ ++DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); ++int DSA_bits(const DSA *dsa); ++void DSA_get0_key(const DSA *d, ++ const BIGNUM **pub_key, const BIGNUM **priv_key); ++int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); ++void DSA_get0_pqg(const DSA *d, ++ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); ++int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); ++ ++HMAC_CTX *HMAC_CTX_new(void); ++void HMAC_CTX_free(HMAC_CTX *ctx); ++ ++EVP_MD_CTX *EVP_MD_CTX_new(void); ++int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); ++void EVP_MD_CTX_free(EVP_MD_CTX *ctx); ++void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, ++ const X509_ALGOR **palg); ++X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req); ++int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, ++ const unsigned char **pk, int *ppklen, ++ X509_ALGOR **pa, X509_PUBKEY *pub); ++const ASN1_INTEGER *X509_get0_serialNumber(const X509 *a); ++const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x); ++int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); ++const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x); ++int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm); ++const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x); ++const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const X509_REVOKED *r); ++const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl); ++ ++void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, ++ const X509_ALGOR **palg); ++ ++const ASN1_INTEGER *TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *a); ++const STACK_OF(ASN1_UTF8STRING) *TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *a); ++const ASN1_BIT_STRING *TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *a); ++ ++ ++int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int f); ++int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int f); ++BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *b); ++X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s); ++STACK_OF(X509) *TS_VERIFY_CTS_set_certs(TS_VERIFY_CTX *ctx, ++ STACK_OF(X509) *certs); ++unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx, ++ unsigned char *hexstr, ++ long len); ++ ++#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER) ++int i2d_re_X509_tbs(X509 *x, unsigned char **pp); ++#endif ++#if OPENSSL_VERSION_NUMBER < 0x10002000L ++void X509_get0_signature(CONSTIFY_X509_get0 ASN1_BIT_STRING **psig, ++ CONSTIFY_X509_get0 X509_ALGOR **palg, ++ const X509 *x); ++int X509_get_signature_nid(const X509 *x); ++#endif ++ ++#endif ++ + #define AUXILIAR_SETOBJECT(L, cval, ltype, idx, lvar) \ + do { \ + int n = (idx < 0)?idx-1:idx; \ +@@ -51,7 +165,7 @@ + const char* bn = luaL_checklstring(L,-1,&l); \ + if(_type->_name==NULL) _type->_name = BN_new(); \ + BN_bin2bn((const unsigned char *)bn,l,_type->_name); \ +- }else if(auxiliar_isclass(L,"openssl.bn",-1)) { \ ++ }else if(auxiliar_getclassudata(L,"openssl.bn",-1)) { \ + const BIGNUM* bn = CHECK_OBJECT(-1,BIGNUM,"openssl.bn"); \ + if(_type->_name==NULL) _type->_name = BN_new(); \ + BN_copy(_type->_name, bn); \ +@@ -77,7 +191,7 @@ extern const char* format[]; + + BIO* load_bio_object(lua_State* L, int idx); + int bio_is_der(BIO* bio); +-const EVP_MD* get_digest(lua_State* L, int idx); ++const EVP_MD* get_digest(lua_State* L, int idx, const char* def_alg); + const EVP_CIPHER* get_cipher(lua_State* L, int idx, const char* def_alg); + BIGNUM *BN_get(lua_State *L, int i); + int openssl_engine(lua_State *L); +@@ -87,14 +201,13 @@ void to_hex(const char* in, int length, + + int openssl_push_asn1type(lua_State* L, const ASN1_TYPE* type); + int openssl_push_asn1object(lua_State* L, const ASN1_OBJECT* obj); +-int openssl_push_asn1(lua_State* L, ASN1_STRING* string, int type); +-int openssl_push_x509_algor(lua_State*L, const X509_ALGOR* alg); ++int openssl_push_asn1(lua_State* L, const ASN1_STRING* string, int type); + int openssl_push_general_name(lua_State*L, const GENERAL_NAME* name); + +-#define PUSH_ASN1_TIME(L, tm) openssl_push_asn1(L, (ASN1_STRING*)tm, V_ASN1_UTCTIME) +-#define PUSH_ASN1_INTEGER(L, i) openssl_push_asn1(L, (ASN1_STRING*)i, V_ASN1_INTEGER) +-#define PUSH_ASN1_OCTET_STRING(L, s) openssl_push_asn1(L, (ASN1_STRING*)s, V_ASN1_OCTET_STRING) +-#define PUSH_ASN1_STRING(L, s) openssl_push_asn1(L, (ASN1_STRING*)s, V_ASN1_UNDEF) ++#define PUSH_ASN1_TIME(L, tm) openssl_push_asn1(L, (ASN1_STRING*)(tm), V_ASN1_UTCTIME) ++#define PUSH_ASN1_INTEGER(L, i) openssl_push_asn1(L, (ASN1_STRING*)(i), V_ASN1_INTEGER) ++#define PUSH_ASN1_OCTET_STRING(L, s) openssl_push_asn1(L, (ASN1_STRING*)(s), V_ASN1_OCTET_STRING) ++#define PUSH_ASN1_STRING(L, s) openssl_push_asn1(L, (ASN1_STRING*)(s), V_ASN1_UNDEF) + + int openssl_push_xname_asobject(lua_State*L, X509_NAME* xname); + int openssl_push_bit_string_bitname(lua_State* L, const BIT_STRING_BITNAME* name); +@@ -112,27 +225,42 @@ int openssl_register_xalgor(lua_State*L) + + int openssl_pushresult(lua_State*L, int result); + +-int openssl_newvalue(lua_State*L, void*p); +-int openssl_freevalue(lua_State*L, void*p); +-int openssl_setvalue(lua_State*L, void*p, const char*field); +-int openssl_getvalue(lua_State*L, void*p, const char*field); +-int openssl_refrence(lua_State*L, void*p, int op); ++int openssl_newvalue(lua_State*L, const void*p); ++int openssl_freevalue(lua_State*L, const void*p); ++int openssl_valueset(lua_State*L, const void*p, const char*field); ++int openssl_valueget(lua_State*L, const void*p, const char*field); ++int openssl_valueseti(lua_State*L, const void*p, int i); ++int openssl_valuegeti(lua_State*L, const void*p, int i); ++size_t openssl_valuelen(lua_State*L, const void*p); ++int openssl_refrence(lua_State*L, const void*p, int op); + + int openssl_verify_cb(int preverify_ok, X509_STORE_CTX *xctx); + int openssl_cert_verify_cb(X509_STORE_CTX *xctx, void* u); + void openssl_xstore_free(X509_STORE* ctx); + + STACK_OF(X509)* openssl_sk_x509_fromtable(lua_State *L, int idx); +-int openssl_sk_x509_totable(lua_State *L, STACK_OF(X509)* sk); ++int openssl_sk_x509_totable(lua_State *L, const STACK_OF(X509)* sk); + STACK_OF(X509_CRL)* openssl_sk_x509_crl_fromtable(lua_State *L, int idx); +-int openssl_sk_x509_crl_totable(lua_State *L, STACK_OF(X509_CRL)* sk); ++int openssl_sk_x509_crl_totable(lua_State *L, const STACK_OF(X509_CRL)* sk); + STACK_OF(X509_EXTENSION)* openssl_sk_x509_extension_fromtable(lua_State *L, int idx); +-int openssl_sk_x509_extension_totable(lua_State *L, STACK_OF(X509_EXTENSION)* sk); +-int openssl_sk_x509_algor_totable(lua_State *L, STACK_OF(X509_ALGOR)* sk); +-int openssl_sk_x509_name_totable(lua_State *L, STACK_OF(X509_NAME)* sk); ++int openssl_sk_x509_extension_totable(lua_State *L, const STACK_OF(X509_EXTENSION)* sk); ++int openssl_sk_x509_algor_totable(lua_State *L, const STACK_OF(X509_ALGOR)* sk); ++int openssl_sk_x509_name_totable(lua_State *L, const STACK_OF(X509_NAME)* sk); + + X509_ATTRIBUTE* openssl_new_xattribute(lua_State*L, X509_ATTRIBUTE** a, int idx, const char* eprefix); + ++#if !defined(OPENSSL_NO_SRP) ++#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER <= 0x10002000 ++#define OPENSSL_NO_SRP ++#endif ++#endif ++ + #ifdef HAVE_USER_CUSTOME + #include HAVE_USER_CUSTOME + #endif ++ ++#if defined(__cplusplus) ++} ++#endif ++ ++#endif /* OPENSSL_PRIVATE_H */ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/rsa.c luvi-src-v2.7.6/deps/lua-openssl/src/rsa.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/rsa.c 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/rsa.c 2019-02-13 11:53:24.321792707 +0100 +@@ -7,19 +7,12 @@ + #include "openssl.h" + #include "private.h" + #include ++#include + + #define MYNAME "rsa" + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + +-#define lua_boxpointer(L,u) \ +- (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u)) +- +-#define PUSH_BN(x) \ +-lua_boxpointer(L,x); \ +-luaL_getmetatable(L,"openssl.bn"); \ +-lua_setmetatable(L,-2) +- + static LUA_FUNCTION(openssl_rsa_free) + { + RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); +@@ -29,11 +22,9 @@ static LUA_FUNCTION(openssl_rsa_free) + + static int is_private(const RSA* rsa) + { +- if (NULL == rsa->p || NULL == rsa->q) +- { +- return 0; +- } +- return 1; ++ const BIGNUM* d = NULL; ++ RSA_get0_key(rsa, NULL, NULL, &d); ++ return d != NULL && !BN_is_zero(d); + }; + + static LUA_FUNCTION(openssl_rsa_isprivate) +@@ -43,21 +34,29 @@ static LUA_FUNCTION(openssl_rsa_isprivat + return 1; + }; + ++static LUA_FUNCTION(openssl_rsa_size) ++{ ++ RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); ++ lua_pushinteger(L, RSA_size(rsa)); ++ return 1; ++}; ++ + static LUA_FUNCTION(openssl_rsa_encrypt) + { + RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); + size_t l; + const unsigned char* from = (const unsigned char *)luaL_checklstring(L, 2, &l); + int padding = openssl_get_padding(L, 3, "pkcs1"); ++ int ispriv = lua_isnone(L, 4) ? is_private(rsa) : lua_toboolean(L, 4); + unsigned char* to = OPENSSL_malloc(RSA_size(rsa)); + int flen = l; + +- flen = is_private(rsa) ++ flen = ispriv + ? RSA_private_encrypt(flen, from, to, rsa, padding) + : RSA_public_encrypt(flen, from, to, rsa, padding); + if (flen > 0) + { +- lua_pushlstring(L, to, flen); ++ lua_pushlstring(L, (const char*)to, flen); + OPENSSL_free(to); + return 1; + } +@@ -71,15 +70,16 @@ static LUA_FUNCTION(openssl_rsa_decrypt) + size_t l; + const unsigned char* from = (const unsigned char *) luaL_checklstring(L, 2, &l); + int padding = openssl_get_padding(L, 3, "pkcs1"); ++ int ispriv = lua_isnone(L, 4) ? is_private(rsa) : lua_toboolean(L, 4); + unsigned char* to = OPENSSL_malloc(RSA_size(rsa)); + int flen = l; + +- flen = is_private(rsa) ++ flen = ispriv + ? RSA_private_decrypt(flen, from, to, rsa, padding) + : RSA_public_decrypt(flen, from, to, rsa, padding); + if (flen > 0) + { +- lua_pushlstring(L, to, flen); ++ lua_pushlstring(L, (const char*)to, flen); + OPENSSL_free(to); + return 1; + } +@@ -87,27 +87,111 @@ static LUA_FUNCTION(openssl_rsa_decrypt) + return openssl_pushresult(L, flen); + }; + ++static LUA_FUNCTION(openssl_rsa_sign) ++{ ++ RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); ++ size_t l; ++ const unsigned char* msg = (const unsigned char *)luaL_checklstring(L, 2, &l); ++ int type = luaL_optint(L, 3, NID_md5_sha1); ++ unsigned char* sig = OPENSSL_malloc(RSA_size(rsa)); ++ int flen = l; ++ unsigned int slen = RSA_size(rsa); ++ ++ int ret = RSA_sign(type, msg, flen, sig, &slen, rsa); ++ if (ret == 1) ++ { ++ lua_pushlstring(L, (const char*)sig, slen); ++ OPENSSL_free(sig); ++ return 1; ++ } ++ OPENSSL_free(sig); ++ return openssl_pushresult(L, ret); ++}; ++ ++static LUA_FUNCTION(openssl_rsa_verify) ++{ ++ RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); ++ size_t l; ++ const unsigned char* from = (const unsigned char *)luaL_checklstring(L, 2, &l); ++ size_t s; ++ const unsigned char* sig = (const unsigned char *)luaL_checklstring(L, 3, &s); ++ int type = luaL_optint(L, 4, NID_md5_sha1); ++ int flen = l; ++ int slen = s; ++ ++ int ret = RSA_verify(type, from, flen, sig, slen, rsa); ++ return openssl_pushresult(L, ret); ++}; ++ + static LUA_FUNCTION(openssl_rsa_parse) + { ++ const BIGNUM *n = NULL, *e = NULL, *d = NULL; ++ const BIGNUM *p = NULL, *q = NULL; ++ const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; ++ + RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); ++ RSA_get0_key(rsa, &n, &e, &d); ++ RSA_get0_factors(rsa, &p, &q); ++ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); ++ ++ + lua_newtable(L); +- OPENSSL_PKEY_GET_BN(rsa->n, n); +- OPENSSL_PKEY_GET_BN(rsa->e, e); +- OPENSSL_PKEY_GET_BN(rsa->d, d); +- OPENSSL_PKEY_GET_BN(rsa->p, p); +- OPENSSL_PKEY_GET_BN(rsa->q, q); +- OPENSSL_PKEY_GET_BN(rsa->dmp1, dmp1); +- OPENSSL_PKEY_GET_BN(rsa->dmq1, dmq1); +- OPENSSL_PKEY_GET_BN(rsa->iqmp, iqmp); ++ lua_pushinteger(L, RSA_size(rsa)); ++ lua_setfield(L, -2, "size"); ++ lua_pushinteger(L, RSA_bits(rsa)); ++ lua_setfield(L, -2, "bits"); ++ OPENSSL_PKEY_GET_BN(n, n); ++ OPENSSL_PKEY_GET_BN(e, e); ++ OPENSSL_PKEY_GET_BN(d, d); ++ OPENSSL_PKEY_GET_BN(p, p); ++ OPENSSL_PKEY_GET_BN(q, q); ++ OPENSSL_PKEY_GET_BN(dmp1, dmp1); ++ OPENSSL_PKEY_GET_BN(dmq1, dmq1); ++ OPENSSL_PKEY_GET_BN(iqmp, iqmp); ++ return 1; ++} ++ ++static LUA_FUNCTION(openssl_rsa_read) ++{ ++ size_t l; ++ const char* data = luaL_checklstring(L, 1, &l); ++ const unsigned char* in = (const unsigned char*)data; ++ RSA *rsa = d2i_RSAPrivateKey(NULL, &in, l); ++ if (rsa == NULL) ++ { ++ in = (const unsigned char*)data; ++ rsa = d2i_RSA_PUBKEY(NULL, &in, l); ++ } ++ if (rsa) ++ PUSH_OBJECT(rsa, "openssl.rsa"); ++ else ++ lua_pushnil(L); + return 1; + } + ++static int openssl_rsa_set_method(lua_State *L) ++{ ++ RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); ++ ENGINE *e = CHECK_OBJECT(2, ENGINE, "openssl.engine"); ++ const RSA_METHOD *m = ENGINE_get_RSA(e); ++ if (m) ++ { ++ int r = RSA_set_method(rsa, m); ++ return openssl_pushresult(L, r); ++ } ++ return 0; ++} ++ + static luaL_Reg rsa_funs[] = + { + {"parse", openssl_rsa_parse}, + {"isprivate", openssl_rsa_isprivate}, + {"encrypt", openssl_rsa_encrypt}, + {"decrypt", openssl_rsa_decrypt}, ++ {"sign", openssl_rsa_sign}, ++ {"verify", openssl_rsa_verify}, ++ {"size", openssl_rsa_size}, ++ {"set_method", openssl_rsa_set_method}, + + {"__gc", openssl_rsa_free}, + {"__tostring", auxiliar_tostring}, +@@ -121,6 +205,10 @@ static luaL_Reg R[] = + {"isprivate", openssl_rsa_isprivate}, + {"encrypt", openssl_rsa_encrypt}, + {"decrypt", openssl_rsa_decrypt}, ++ {"sign", openssl_rsa_sign}, ++ {"verify", openssl_rsa_verify}, ++ {"size", openssl_rsa_size}, ++ {"read", openssl_rsa_read}, + + {NULL, NULL} + }; +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/sk.h luvi-src-v2.7.6/deps/lua-openssl/src/sk.h +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/sk.h 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/sk.h 2019-02-13 11:53:24.321792707 +0100 +@@ -1,18 +1,28 @@ +-/*=========================================================================*\ +-* sk.h +-* stack routines(MACRO) for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++Provide STACK_OF(object) maintance in lua. ++STACK\_OF(CTYPE) object just like STACK\_OF(X509) are high frequency used, ++in x509, pkcs7, pkcs12 and others module, and it has complex APIs in openssl. ++In lua-openssl, all of STACK\_OF(CTYPE) C side objects are mapping to array ++actually table in Lua side, and follow the rules of the Lua array, start ++index from 1, not 0 in C world. ++E.g C side STACK\_OF(X509) and Lua side array {cert1,cert2,...,certn} can ++be automatic convert in lua\-openssl if need. + ++@module sk ++*/ + #include "openssl.h" + + #ifdef CRYPTO_LOCK_REF ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + #define REF_OR_DUP(TYPE, x) CRYPTO_add(&x->references,1,CRYPTO_LOCK_##TYPE) + #else ++#define REF_OR_DUP(TYPE, x) TYPE##_up_ref(x) ++#endif ++#else + #define REF_OR_DUP(TYPE, x) x = TYPE##_dup(x) + #endif + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + #define TAB2SK(TYPE, type) \ + STACK_OF(TYPE)* openssl_sk_##type##_fromtable(lua_State*L, int idx) { \ + STACK_OF(TYPE) * sk; \ +@@ -35,7 +45,7 @@ STACK_OF(TYPE)* openssl_sk_##type##_from + } + + +-#define SK2TAB(TYPE,type) int openssl_sk_##type##_totable(lua_State* L, STACK_OF(TYPE) *sk) { \ ++#define SK2TAB(TYPE,type) int openssl_sk_##type##_totable(lua_State* L,const STACK_OF(TYPE) *sk) { \ + int i=0, n=0; \ + lua_newtable(L); \ + n = SKM_sk_num(TYPE, sk); \ +@@ -47,6 +57,42 @@ STACK_OF(TYPE)* openssl_sk_##type##_from + } \ + return 1; \ + } ++#else ++#define TAB2SK(TYPE, type) \ ++STACK_OF(TYPE)* openssl_sk_##type##_fromtable(lua_State*L, int idx) { \ ++ STACK_OF(TYPE) * sk; \ ++ luaL_argcheck(L, lua_istable(L, idx), idx, \ ++ "must be a table as array or nil"); \ ++ sk = sk_##TYPE##_new_null(); \ ++ if (lua_istable(L,idx)) { \ ++ int n = lua_rawlen(L, idx); \ ++ int i; \ ++ for ( i=0; i ++#include ++ ++#define MYNAME "srp" ++#define MYVERSION MYNAME " library for " LUA_VERSION " / May 2018 / "\ ++ "based on OpenSSL " SHLIB_VERSION_NUMBER ++ ++/* server side */ ++static int openssl_srp_create_verifier(lua_State *L) ++{ ++ const SRP_gN *GN = CHECK_OBJECT(1, SRP_gN, "openssl.srp_gn"); ++ const char *username = luaL_checkstring(L, 2); ++ const char *servpass = luaL_checkstring(L, 3); ++ BIGNUM *salt = NULL, *verifier = NULL; ++ int ret = SRP_create_verifier_BN(username, servpass, &salt, &verifier, GN->N, GN->g); ++ if (ret==1) ++ { ++ PUSH_OBJECT(salt, "openssl.bn"); ++ PUSH_OBJECT(verifier, "openssl.bn"); ++ return 2; ++ } ++ return openssl_pushresult(L, ret); ++} ++ ++#ifndef BN_RAND_TOP_ANY ++#define BN_RAND_TOP_ANY -1 ++#endif ++#ifndef BN_RAND_BOTTOM_ANY ++#define BN_RAND_BOTTOM_ANY 0 ++#endif ++ ++static int openssl_srp_calc_b(lua_State *L) ++{ ++ int ret = 0; ++ const SRP_gN *GN = CHECK_OBJECT(1, SRP_gN, "openssl.srp_gn"); ++ BIGNUM *v = CHECK_OBJECT(2, BIGNUM, "openssl.bn"); ++ int bits = luaL_optint(L, 3, 32*8); ++ ++ BIGNUM *Brnd = NULL, *Bpub = NULL; ++ Brnd = BN_new(); ++ ++ ret = BN_rand(Brnd, bits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY); ++ if (ret==1) ++ { ++ /* Server's first message */ ++ Bpub = SRP_Calc_B(Brnd, GN->N, GN->g, v); ++ ret = SRP_Verify_B_mod_N(Bpub, GN->N); ++ if(ret==1) ++ { ++ PUSH_OBJECT(Bpub, "openssl.bn"); ++ PUSH_OBJECT(Brnd, "openssl.bn"); ++ ret = 2; ++ } ++ } ++ if(ret!=2) ++ { ++ ret = openssl_pushresult(L, ret); ++ if(Brnd) BN_free(Brnd); ++ if(Bpub) BN_free(Bpub); ++ } ++ return ret; ++} ++ ++static int openssl_srp_calc_server_key(lua_State *L) ++{ ++ const SRP_gN *GN = CHECK_OBJECT(1, SRP_gN, "openssl.srp_gn"); ++ BIGNUM *Apub = CHECK_OBJECT(2, BIGNUM, "openssl.bn"); ++ BIGNUM *v = CHECK_OBJECT(3, BIGNUM, "openssl.bn"); ++ BIGNUM *u = CHECK_OBJECT(4, BIGNUM, "openssl.bn"); ++ BIGNUM *Brnd = CHECK_OBJECT(5, BIGNUM, "openssl.bn"); ++ ++ /* Server's key */ ++ BIGNUM *Kserver = SRP_Calc_server_key(Apub, v, u, Brnd, GN->N); ++ PUSH_OBJECT(Kserver, "openssl.bn"); ++ return 1; ++} ++ ++/* client side */ ++static int openssl_srp_calc_a(lua_State *L) ++{ ++ int ret = 0; ++ const SRP_gN *GN = CHECK_OBJECT(1, SRP_gN, "openssl.srp_gn"); ++ int bits = luaL_optint(L, 3, 32*8); ++ ++ BIGNUM *Arnd = NULL, *Apub = NULL; ++ Arnd = BN_new(); ++ ++ ret = BN_rand(Arnd, bits, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY); ++ if (ret==1) ++ { ++ /* Client's response */ ++ Apub = SRP_Calc_A(Arnd, GN->N, GN->g); ++ ret = SRP_Verify_A_mod_N(Apub, GN->N); ++ if(ret==1) ++ { ++ PUSH_OBJECT(Apub, "openssl.bn"); ++ PUSH_OBJECT(Arnd, "openssl.bn"); ++ ret = 2; ++ } ++ } ++ if(ret!=2) ++ { ++ ret = openssl_pushresult(L, ret); ++ if(Arnd) BN_free(Arnd); ++ if(Apub) BN_free(Apub); ++ } ++ return ret; ++} ++ ++static int openssl_srp_calc_x(lua_State *L) ++{ ++ BIGNUM *s = CHECK_OBJECT(1, BIGNUM, "openssl.bn"); ++ const char *username = luaL_checkstring(L, 2); ++ const char *password = luaL_checkstring(L, 3); ++ ++ BIGNUM *x = SRP_Calc_x(s, username, password); ++ PUSH_OBJECT(x, "openssl.bn"); ++ return 1; ++} ++ ++static int openssl_srp_calc_client_key(lua_State *L) ++{ ++ const SRP_gN *GN = CHECK_OBJECT(1, SRP_gN, "openssl.srp_gn"); ++ BIGNUM *Bpub = CHECK_OBJECT(2, BIGNUM, "openssl.bn"); ++ BIGNUM *x = CHECK_OBJECT(3, BIGNUM, "openssl.bn"); ++ BIGNUM *Arnd = CHECK_OBJECT(4, BIGNUM, "openssl.bn"); ++ BIGNUM *u = CHECK_OBJECT(5, BIGNUM, "openssl.bn"); ++ ++ /* Client's key */ ++ BIGNUM *Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, Arnd, u); ++ PUSH_OBJECT(Kclient, "openssl.bn"); ++ return 1; ++} ++ ++/* both side */ ++static int openssl_srp_get_default_gN(lua_State *L) ++{ ++ const char *id = luaL_checkstring(L, 1); ++ SRP_gN *GN = SRP_get_default_gN(id); ++ if(GN) ++ PUSH_OBJECT(GN, "openssl.srp_gn"); ++ else ++ lua_pushnil(L); ++ return 1; ++} ++ ++static int openssl_srp_calc_u(lua_State *L) ++{ ++ const SRP_gN *GN = CHECK_OBJECT(1, SRP_gN, "openssl.srp_gn"); ++ BIGNUM *Apub = CHECK_OBJECT(2, BIGNUM, "openssl.bn"); ++ BIGNUM *Bpub = CHECK_OBJECT(3, BIGNUM, "openssl.bn"); ++ ++ /* Both sides calculate u */ ++ BIGNUM *u = SRP_Calc_u(Apub, Bpub, GN->N); ++ PUSH_OBJECT(u, "openssl.bn"); ++ return 1; ++} ++ ++static luaL_Reg srp_funs[] = ++{ ++ /* both side */ ++ {"calc_u", openssl_srp_calc_u}, ++ ++ /* client side */ ++ {"calc_a", openssl_srp_calc_a}, ++ {"calc_x", openssl_srp_calc_x}, ++ {"calc_client_key", openssl_srp_calc_client_key}, ++ ++ /* server side */ ++ {"calc_b", openssl_srp_calc_b}, ++ {"create_verifier", openssl_srp_create_verifier}, ++ {"calc_server_key", openssl_srp_calc_server_key}, ++ ++ /* prototype */ ++ {"__tostring", auxiliar_tostring}, ++ ++ {NULL, NULL } ++}; ++ ++static luaL_Reg R[] = ++{ ++ {"get_default_gN", openssl_srp_get_default_gN}, ++ ++ {NULL, NULL} ++}; ++ ++int luaopen_srp(lua_State *L) ++{ ++ auxiliar_newclass(L, "openssl.srp_gn", srp_funs); ++ ++ lua_newtable(L); ++ luaL_setfuncs(L, R, 0); ++ lua_pushliteral(L, "version"); ++ lua_pushliteral(L, MYVERSION); ++ lua_settable(L, -3); ++ return 1; ++} ++#endif +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/ssl.c luvi-src-v2.7.6/deps/lua-openssl/src/ssl.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/ssl.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/ssl.c 2019-02-13 11:53:24.321792707 +0100 +@@ -1,9 +1,10 @@ +-/*=========================================================================*\ +-* ssl.c +-* SSL modules for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++ssl modules for lua-openssl binding, provide ssl function in lua. ++ ++@module ssl ++@usage ++ ssl = require('openssl').ssl ++*/ + #include "openssl.h" + #include "private.h" + #include +@@ -15,6 +16,13 @@ + + #include + ++/*** ++create ssl_ctx object, which mapping to SSL_CTX in openssl. ++@function ctx_new ++@tparam string protocol support 'SSLv3', 'SSLv23', 'SSLv2', 'TSLv1', 'TSLv1_1','TSLv1_2','DTLSv1', and can be follow by '_server' or '_client' ++@tparam[opt] string support_ciphers, if not given, default of openssl will be used ++@treturn ssl_ctx ++*/ + static int openssl_ssl_ctx_new(lua_State*L) + { + const char* meth = luaL_optstring(L, 1, "TLSv1"); +@@ -24,12 +32,17 @@ static int openssl_ssl_ctx_new(lua_State + SSL_METHOD* method = NULL; + const char* ciphers; + SSL_CTX* ctx; +- if (strcmp(meth, "SSLv3") == 0) ++ if (0); ++ ++#ifndef OPENSSL_NO_SSL3 ++ else if (strcmp(meth, "SSLv3") == 0) + method = SSLv3_method(); /* SSLv3 */ + else if (strcmp(meth, "SSLv3_server") == 0) + method = SSLv3_server_method(); /* SSLv3 */ + else if (strcmp(meth, "SSLv3_client") == 0) + method = SSLv3_client_method(); /* SSLv3 */ ++#endif ++ + else if (strcmp(meth, "SSLv23") == 0) + method = SSLv23_method(); /* SSLv3 but can rollback to v2 */ + else if (strcmp(meth, "SSLv23_server") == 0) +@@ -73,22 +86,21 @@ static int openssl_ssl_ctx_new(lua_State + else if (strcmp(meth, "SSLv2_client") == 0) + method = SSLv2_client_method(); + #endif ++#endif + #ifdef LOAD_SSL_CUSTOM + LOAD_SSL_CUSTOM + #endif +- +-#endif + else + luaL_error(L, "#1:%s not supported\n" +- "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n", +- "default is SSLv3", ++ "Maybe [SSLv3] SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n" ++ "default is TLSv1", + meth); + ciphers = luaL_optstring(L, 2, SSL_DEFAULT_CIPHER_LIST); + ctx = SSL_CTX_new(method); + if (!ctx) + luaL_error(L, "#1:%s not supported\n" +- "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n", +- "default is SSLv3", ++ "Maybe [SSLv3] SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n" ++ "default is TLSv1", + meth); + openssl_newvalue(L, ctx); + SSL_CTX_set_cipher_list(ctx, ciphers); +@@ -98,6 +110,14 @@ static int openssl_ssl_ctx_new(lua_State + return 1; + } + ++/*** ++get alert_string for ssl state ++@function alert_string ++@tparam number alert ++@tparam[opt=false] boolean long ++@treturn string alert type ++@treturn string desc string, if long set true will return long info ++*/ + static int openssl_ssl_alert_string(lua_State*L) + { + int v = luaL_checkint(L, 1); +@@ -119,16 +139,66 @@ static int openssl_ssl_alert_string(lua_ + return 2; + } + ++static int openssl_ssl_session_new(lua_State*L) ++{ ++ SSL_SESSION *ss = SSL_SESSION_new(); ++ PUSH_OBJECT(ss, "openssl.ssl_session"); ++ return 1; ++} ++ ++static int openssl_ssl_session_read(lua_State*L) ++{ ++ BIO *in = load_bio_object(L, 1); ++ SSL_SESSION* ss = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL); ++ if (!ss) ++ { ++ (void)BIO_reset(in); ++ ss = d2i_SSL_SESSION_bio(in, NULL); ++ } ++ BIO_free(in); ++ if (ss) ++ { ++ PUSH_OBJECT(ss, "openssl.ssl_session"); ++ return 1; ++ } ++ return openssl_pushresult(L, 0); ++} ++ ++static luaL_Reg R[] = ++{ ++ {"ctx_new", openssl_ssl_ctx_new }, ++ {"alert_string", openssl_ssl_alert_string }, ++ ++ {"session_new", openssl_ssl_session_new}, ++ {"session_read", openssl_ssl_session_read}, ++ {NULL, NULL} ++}; ++ + /****************************SSL CTX********************************/ ++/*** ++openssl.ssl_ctx object ++@type ssl_ctx ++*/ ++ ++/*** ++tell ssl_ctx use private key and certificate, and check private key ++@function use ++@tparam evp_pkey pkey ++@tparam x509 cert ++@treturn boolean result return true for ok, or nil followed by errmsg and errval ++*/ + static int openssl_ssl_ctx_use(lua_State*L) + { + int ret; + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); + EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); +- X509* cert = CHECK_OBJECT(3, X509, "openssl.x509"); + +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 2, "must be private key"); +- ret = SSL_CTX_use_certificate(ctx, cert); ++ if(lua_isstring(L, 3)) { ++ ret = SSL_CTX_use_certificate_chain_file(ctx, luaL_checkstring(L, 3)); ++ } else { ++ X509* cert = CHECK_OBJECT(3, X509, "openssl.x509"); ++ ret = SSL_CTX_use_certificate(ctx, cert); ++ } + if (ret == 1) + { + ret = SSL_CTX_use_PrivateKey(ctx, pkey); +@@ -140,6 +210,13 @@ static int openssl_ssl_ctx_use(lua_State + return openssl_pushresult(L, ret); + } + ++/*** ++add client ca cert and option extra chain cert ++@function add ++@tparam x509 clientca ++@tparam[opt] table extra_chain_cert_array ++@treturn boolean result ++*/ + static int openssl_ssl_ctx_add(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -155,7 +232,7 @@ static int openssl_ssl_ctx_add(lua_State + lua_rawgeti(L, 3, i); + x = CHECK_OBJECT(2, X509, "openssl.x509"); + lua_pop(L, 1); +- CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); ++ X509_up_ref(x); + ret = SSL_CTX_add_extra_chain_cert(ctx, x); + } + } +@@ -181,6 +258,17 @@ static int openssl_ssl_ctx_gc(lua_State* + return 0; + } + ++/*** ++get timeout ++@function timeout ++@return number ++*/ ++/*** ++set timeout ++@function timeout ++@tparam number timeout ++@treturn number previous timeout ++*/ + static int openssl_ssl_ctx_timeout(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -220,6 +308,23 @@ static const char* sMode_options[] = + NULL + }; + ++/*** ++clean given mode ++mode support 'enable_partial_write','accept_moving_write_buffer','auto_retry','no_auto_chain','release_buffers' ++@function mode ++@tparam boolean clear must be true ++@tparam string mode ++@param[opt] ... ++@treturn string ++@treturn ... ++@usage ++ modes = { ssl_ctx:mode('enable_partial_write','accept_moving_write_buffer','auto_retry') }, ++ ++ for i, v in ipairs(modes) ++ print(v) ++ end ++ --output 'enable_partial_write','accept_moving_write_buffer','auto_retry' ++*/ + static int openssl_ssl_ctx_mode(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -253,7 +358,30 @@ static int openssl_ssl_ctx_mode(lua_Stat + return ret; + }; + ++/*** ++get options ++@function options ++@treturn table string list of current options ++*/ + ++/*** ++set options ++@function options ++@tparam string option, support "microsoft_sess_id_bug", "netscape_challenge_bug", "netscape_reuse_cipher_change_bug", ++"sslref2_reuse_cert_type_bug", "microsoft_big_sslv3_buffer", "msie_sslv3_rsa_padding","ssleay_080_client_dh_bug", ++"tls_d5_bug","tls_block_padding_bug","dont_insert_empty_fragments","all", please to see ssl_options.h ++@treturn table string list of current options after set new option ++*/ ++ ++/*** ++clear options ++@function options ++@tparam boolean clear set true to clear options ++@tparam string option, support "microsoft_sess_id_bug", "netscape_challenge_bug", "netscape_reuse_cipher_change_bug", ++"sslref2_reuse_cert_type_bug", "microsoft_big_sslv3_buffer", "msie_sslv3_rsa_padding","ssleay_080_client_dh_bug", ++"tls_d5_bug","tls_block_padding_bug","dont_insert_empty_fragments","all", please to see ssl_options.h ++@treturn table string list of current options after clear some option ++*/ + static int openssl_ssl_ctx_options(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -275,8 +403,8 @@ static int openssl_ssl_ctx_options(lua_S + int j; + for (j = 0; ssl_options[j].name; j++) + { +- LuaL_Enum e = ssl_options[j]; +- if (strcasecmp(s, e.name)) ++ LuaL_Enumeration e = ssl_options[j]; ++ if (strcasecmp(s, e.name) == 0) + { + options |= e.val; + break; +@@ -285,7 +413,6 @@ static int openssl_ssl_ctx_options(lua_S + } + } + +- + if (clear != 0) + options = SSL_CTX_clear_options(ctx, options); + else +@@ -298,8 +425,8 @@ static int openssl_ssl_ctx_options(lua_S + ret = 0; + for (i = 0; ssl_options[i].name; i++) + { +- LuaL_Enum e = ssl_options[i]; +- if (options && e.val) ++ LuaL_Enumeration e = ssl_options[i]; ++ if (options & e.val) + { + lua_pushstring(L, e.name); + ret++; +@@ -309,6 +436,25 @@ static int openssl_ssl_ctx_options(lua_S + return 1; + } + ++/*** ++get quit_shutdown is set or not ++Normally when a SSL connection is finished, the parties must send out ++"close notify" alert messages using ***SSL:shutdown"*** for a clean shutdown. ++@function quiet_shutdown ++@treturn boolean result ++*/ ++/*** ++set quiet_shutdown ++@function quiet_shutdown ++@tparam boolean quiet ++When setting the "quiet shutdown" flag to 1, ***SSL:shutdown*** will set the internal flags ++to SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN. ***SSL:shutdown*** then behaves like ++***SSL:set_shutdown*** called with SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN. ++The session is thus considered to be shutdown, but no "close notify" alert ++is sent to the peer. This behaviour violates the TLS standard. ++The default is normal shutdown behaviour as described by the TLS standard. ++@treturn boolean result ++*/ + static int openssl_ssl_ctx_quiet_shutdown(lua_State*L) + { + SSL_CTX* s = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -326,6 +472,16 @@ static int openssl_ssl_ctx_quiet_shutdow + } + }; + ++/*** ++set verify locations with cafile and capath ++ssl_ctx:verify_locations specifies the locations for *ctx*, at ++which CA certificates for verification purposes are located. The certificates ++available via *CAfile* and *CApath* are trusted. ++@function verify_locations ++@tparam string cafile ++@tparam string capath ++@treturn boolean result ++*/ + static int openssl_ssl_ctx_load_verify_locations(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -335,22 +491,33 @@ static int openssl_ssl_ctx_load_verify_l + return openssl_pushresult(L, ret); + } + ++/*** ++get certificate verification store of ssl_ctx ++@function cert_store ++@treturn x509_store store ++*/ ++/*** ++set or replaces then certificate verification store of ssl_ctx ++@function cert_store ++@tparam x509_store store ++@treturn x509_store store ++*/ + static int openssl_ssl_ctx_cert_store(lua_State*L) + { ++#if OPENSSL_VERSION_NUMBER > 0x10002000L + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); + X509_STORE *store = NULL; +-#if OPENSSL_VERSION_NUMBER > 0x10002000L + if (lua_isnoneornil(L, 2)) + { + store = SSL_CTX_get_cert_store(ctx); +- CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); ++ X509_STORE_up_ref(store); + PUSH_OBJECT(store, "openssl.x509_store"); + return 1; + } + else + { + store = CHECK_OBJECT(2, X509_STORE, "openssl.x509_store"); +- CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); ++ X509_STORE_up_ref(store); + SSL_CTX_set_cert_store(ctx, store); + X509_STORE_set_trust(store, 1); + return 0; +@@ -361,6 +528,32 @@ static int openssl_ssl_ctx_cert_store(lu + #endif + } + ++#ifndef OPENSSL_NO_ENGINE ++static int openssl_ssl_ctx_set_engine(lua_State*L) ++{ ++ SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); ++ ENGINE* eng = CHECK_OBJECT(2, ENGINE, "openssl.engine"); ++ int ret = SSL_CTX_set_client_cert_engine(ctx, eng); ++ return openssl_pushresult(L, ret); ++} ++#endif ++ ++/****************************************************************************/ ++/*** ++create ssl object ++@function ssl ++@tparam bio bio ++@tparam[opt=false] boolean server, true will make ssl server ++@treturn ssl ++*/ ++/*** ++create ssl object ++@function ssl ++@tparam bio input ++@tparam bio ouput ++@tparam[opt=false] boolean server, true will make ssl server ++@treturn ssl ++*/ + static int openssl_ssl_ctx_new_ssl(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -369,15 +562,15 @@ static int openssl_ssl_ctx_new_ssl(lua_S + SSL *ssl = SSL_new(ctx); + int ret = 1; + +- if (auxiliar_isclass(L, "openssl.bio", 2)) ++ if (auxiliar_getclassudata(L, "openssl.bio", 2)) + { + BIO *bi = CHECK_OBJECT(2, BIO, "openssl.bio"); + BIO *bo = bi; +- CRYPTO_add(&bi->references, 1, CRYPTO_LOCK_BIO); +- if (auxiliar_isclass(L, "openssl.bio", 3)) ++ BIO_up_ref(bi); ++ if (auxiliar_getclassudata(L, "openssl.bio", 3)) + { + bo = CHECK_OBJECT(3, BIO, "openssl.bio"); +- CRYPTO_add(&bo->references, 1, CRYPTO_LOCK_BIO); ++ BIO_up_ref(bo); + mode_idx = 4; + } + else +@@ -415,6 +608,14 @@ static int openssl_ssl_ctx_new_ssl(lua_S + return 1; + } + ++/*** ++create bio object ++@function bio ++@tparam string host_addr format like 'host:port' ++@tparam[opt=false] boolean server, true listen at host_addr,false connect to host_addr ++@tparam[opt=true] boolean autoretry ssl operation autoretry mode ++@treturn bio bio object ++*/ + static int openssl_ssl_ctx_new_bio(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -445,7 +646,7 @@ static int openssl_ssl_ctx_new_bio(lua_S + openssl_newvalue(L, bio); + + lua_pushboolean(L, 1); +- openssl_setvalue(L, bio, "free_all"); ++ openssl_valueset(L, bio, "free_all"); + + return 1; + } +@@ -460,17 +661,17 @@ static int openssl_ssl_ctx_new_bio(lua_S + } + } + +-static int openssl_ssl_getpeerverification(lua_State *L) +-{ +- long err; +- SSL* ssl = CHECK_OBJECT(1, SSL, "openssl.ssl"); +- +- err = SSL_get_verify_result(ssl); +- lua_pushboolean(L, err == X509_V_OK); +- openssl_getvalue(L, ssl, "verify_cert"); +- return 2; +-} +- ++/*** ++get verify depth when cert chain veirition ++@function verify_depth ++@treturn number depth ++*/ ++/*** ++set verify depth when cert chain veirition ++@function verify_depth ++@tparam number depth ++@treturn number depth ++*/ + static int openssl_ssl_ctx_verify_depth(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -503,6 +704,31 @@ static const char* sVerifyMode_Options[] + NULL + }; + ++/*** ++get verify_mode, return number mode and all string modes list ++@function verify_mode ++@treturn number mode_code ++@return ... ++ none: not verify client cert ++ peer: verify client cert ++ fail: if client not have cert, will failure ++ once: verify client only once. ++@usage ++ mode = {ctx:verify_mode()} ++ print('integer mode',mode[1]) ++ for i=2, #mode then ++ print('string mode:'..mode[i]) ++ end ++*/ ++/*** ++set ssl verify mode and callback ++@function verify_mode ++@tparam number mode, mode set to ctx, must be ssl.none or ssl.peer, and ssl.peer support combine with ssl.fail or ssl.once ++@tparam[opt=nil] function ssl verify callback in lua function, not give will use default openssl callback, when mode is 'none', will be ignore this ++verify_cb must be boolean function(verifyarg) prototype, return true to continue or false to end ssl handshake ++verifyarg has field 'error', 'error_string','error_depth','current_cert', and 'preverify_ok' ++@treturn boolean result ++*/ + static int openssl_ssl_ctx_verify_mode(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -522,13 +748,13 @@ static int openssl_ssl_ctx_verify_mode(l + if (lua_isfunction(L, 3)) + { + lua_pushvalue(L, 3); +- openssl_setvalue(L, ctx, "verify_cb"); ++ openssl_valueset(L, ctx, "verify_cb"); + SSL_CTX_set_verify(ctx, mode, openssl_verify_cb); + } + else + { + lua_pushnil(L); +- openssl_setvalue(L, ctx, "verify_cb"); ++ openssl_valueset(L, ctx, "verify_cb"); + SSL_CTX_set_verify(ctx, mode, openssl_verify_cb); + } + return 0; +@@ -568,6 +794,17 @@ static int openssl_ssl_ctx_verify_mode(l + } + } + ++/*** ++set certificate verify callback function ++@function set_cert_verify ++@tparam[opt] function cert_verify_cb with boolean function(verifyargs) prototype, if nil or none will use openssl default callback ++verifyargs has field 'error', 'error_string','error_depth','current_cert' ++*/ ++/*** ++set certificate verify options ++@function set_cert_verify ++@tparam table verify_cb_flag support field always_continue with boolean value and verify_depth with number value. ++*/ + static int openssl_ssl_ctx_set_cert_verify(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -578,13 +815,13 @@ static int openssl_ssl_ctx_set_cert_veri + if (lua_istable(L, 2)) + { + lua_pushvalue(L, 2); +- openssl_setvalue(L, ctx, "verify_cb_flags"); ++ openssl_valueset(L, ctx, "verify_cb_flags"); + SSL_CTX_set_cert_verify_callback(ctx, openssl_cert_verify_cb, L); + } + else if (lua_isfunction(L, 2)) + { + lua_pushvalue(L, 2); +- openssl_setvalue(L, ctx, "cert_verify_cb"); ++ openssl_valueset(L, ctx, "cert_verify_cb"); + SSL_CTX_set_cert_verify_callback(ctx, openssl_cert_verify_cb, L); + } + else +@@ -600,7 +837,7 @@ static DH *tmp_dh_callback(SSL *ssl, int + lua_State *L = SSL_CTX_get_app_data(ctx); + int ret = 0; + /* get callback function */ +- openssl_getvalue(L, ctx, "tmp_dh_callback"); ++ openssl_valueget(L, ctx, "tmp_dh_callback"); + + /* Invoke the callback */ + lua_pushboolean(L, is_export); +@@ -627,7 +864,6 @@ static DH *tmp_dh_callback(SSL *ssl, int + lua_error(L); + } + +- + lua_pop(L, 2); /* Remove values from stack */ + return dh_tmp; + } +@@ -640,7 +876,7 @@ static RSA *tmp_rsa_callback(SSL *ssl, i + lua_State *L = SSL_CTX_get_app_data(ctx); + int ret = 0; + /* get callback function */ +- openssl_getvalue(L, ctx, "tmp_rsa_callback"); ++ openssl_valueget(L, ctx, "tmp_rsa_callback"); + + /* Invoke the callback */ + lua_pushboolean(L, is_export); +@@ -654,11 +890,9 @@ static RSA *tmp_rsa_callback(SSL *ssl, i + lua_pop(L, 2); /* Remove values from stack */ + return NULL; + } +- bio = BIO_new_mem_buf((void*)lua_tostring(L, -1), +- lua_rawlen(L, -1)); ++ bio = BIO_new_mem_buf((void*)lua_tostring(L, -1), lua_rawlen(L, -1)); + if (bio) + { +- + rsa_tmp = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); + BIO_free(bio); + } +@@ -668,7 +902,6 @@ static RSA *tmp_rsa_callback(SSL *ssl, i + lua_error(L); + } + +- + lua_pop(L, 2); /* Remove values from stack */ + return rsa_tmp; + } +@@ -682,7 +915,7 @@ static EC_KEY *tmp_ecdh_callback(SSL *ss + lua_State *L = SSL_CTX_get_app_data(ctx); + int ret = 0; + /* get callback function */ +- openssl_getvalue(L, ctx, "tmp_ecdh_callback"); ++ openssl_valueget(L, ctx, "tmp_ecdh_callback"); + + /* Invoke the callback */ + lua_pushboolean(L, is_export); +@@ -700,7 +933,6 @@ static EC_KEY *tmp_ecdh_callback(SSL *ss + lua_rawlen(L, -1)); + if (bio) + { +- + ec_tmp = PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL); + BIO_free(bio); + } +@@ -710,11 +942,30 @@ static EC_KEY *tmp_ecdh_callback(SSL *ss + lua_error(L); + } + +- + lua_pop(L, 2); /* Remove values from stack */ + return ec_tmp; + } + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++/*** ++set temp callback ++@function set_tmp ++@tparam string keytype, 'dh','ecdh',or 'rsa' ++@tparam function tmp_cb ++@param[opt] vararg ++*/ ++/*** ++set tmp key content pem format ++@function set_tmp ++@tparam string keytype, 'dh','ecdh',or 'rsa' ++@tparam string key_pem ++*/ ++/*** ++set ecdh with given curvename as tmp key ++@function set_tmp ++@tparam string keytype, must be 'ecdh' ++@tparam string curvename ++*/ + static int openssl_ssl_ctx_set_tmp(lua_State *L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -736,20 +987,20 @@ static int openssl_ssl_ctx_set_tmp(lua_S + switch (nwhich) + { + case 0: +- openssl_setvalue(L, ctx, "tmp_dh_callback"); ++ openssl_valueset(L, ctx, "tmp_dh_callback"); + SSL_CTX_set_tmp_dh_callback(ctx, tmp_dh_callback); + break; + case 1: +- openssl_setvalue(L, ctx, "tmp_rsa_callback"); ++ openssl_valueset(L, ctx, "tmp_rsa_callback"); + SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_callback); + break; + case 2: + { + luaL_argcheck(L, lua_isstring(L, 4), 4, "must supply curve name"); +- openssl_setvalue(L, ctx, "tmp_ecdh_callback"); ++ openssl_valueset(L, ctx, "tmp_ecdh_callback"); + SSL_CTX_set_tmp_ecdh_callback(ctx, tmp_ecdh_callback); + lua_pushvalue(L, 4); +- openssl_setvalue(L, ctx, "curve"); ++ openssl_valueset(L, ctx, "curve"); + } + break; + } +@@ -806,6 +1057,7 @@ static int openssl_ssl_ctx_set_tmp(lua_S + + return openssl_pushresult(L, ret); + } ++#endif + + static int tlsext_servername_callback(SSL *ssl, int *ad, void *arg) + { +@@ -820,11 +1072,11 @@ static int tlsext_servername_callback(SS + return SSL_TLSEXT_ERR_NOACK; + + /* Search for the name in the map */ +- openssl_getvalue(L, ctx, "tlsext_servername"); ++ openssl_valueget(L, ctx, "tlsext_servername"); + if (lua_istable(L, -1)) + { + lua_getfield(L, -1, name); +- if (auxiliar_isclass(L, "openssl.ssl_ctx", -1)) ++ if (auxiliar_getclassudata(L, "openssl.ssl_ctx", -1)) + { + newctx = CHECK_OBJECT(-1, SSL_CTX, "openssl.ssl_ctx"); + SSL_set_SSL_CTX(ssl, newctx); +@@ -843,17 +1095,26 @@ static int tlsext_servername_callback(SS + return SSL_TLSEXT_ERR_ALERT_FATAL; + } + ++/*** ++set servername callback ++@function set_servefrname_callback ++@todo ++*/ + static int openssl_ssl_ctx_set_servername_callback(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); + luaL_argcheck(L, lua_istable(L, 2) || lua_isfunction(L, 2), 2, "must be table or function"); + + lua_pushvalue(L, 2); +- openssl_setvalue(L, ctx, "tlsext_servername"); ++ openssl_valueset(L, ctx, "tlsext_servername"); + SSL_CTX_set_tlsext_servername_callback(ctx, tlsext_servername_callback); + return 0; + } + ++/*** ++flush sessions ++@function flush ++*/ + static int openssl_ssl_ctx_flush_sessions(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -862,6 +1123,10 @@ static int openssl_ssl_ctx_flush_session + return 0; + } + ++/*** ++set ssl session ++@function sessions ++*/ + static int openssl_ssl_ctx_sessions(lua_State*L) + { + SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); +@@ -890,6 +1155,18 @@ static int openssl_ssl_ctx_sessions(lua_ + } + } + ++/*** ++get current session cache mode ++@function session_cache_mode ++@treturn table modes as array, mode is 'no_auto_clear','server','client','both','off' ++*/ ++ ++/*** ++set session cache mode,and return old mode ++@function session_cache_mode ++@tparam string mode support 'no_auto_clear','server','client','both','off', ++'no_auto_clear' can be combine with others, so accept one or two param. ++*/ + static int openssl_session_cache_mode(lua_State *L) + { + static const char* smode[] = +@@ -966,12 +1243,19 @@ static int openssl_session_cache_mode(lu + return 1; + } + ++#ifdef SSL_CTX_EXT_DEFINE ++SSL_CTX_EXT_DEFINE ++#endif ++ + static luaL_Reg ssl_ctx_funcs[] = + { + {"ssl", openssl_ssl_ctx_new_ssl}, + {"bio", openssl_ssl_ctx_new_bio}, +- ++#ifndef SSL_CTX_USE_EXT + {"use", openssl_ssl_ctx_use}, ++#else ++ SSL_CTX_USE_EXT ++#endif + {"add", openssl_ssl_ctx_add}, + {"mode", openssl_ssl_ctx_mode}, + {"timeout", openssl_ssl_ctx_timeout}, +@@ -979,16 +1263,20 @@ static luaL_Reg ssl_ctx_funcs[] = + {"quiet_shutdown", openssl_ssl_ctx_quiet_shutdown}, + {"verify_locations", openssl_ssl_ctx_load_verify_locations}, + {"cert_store", openssl_ssl_ctx_cert_store}, +- ++#ifndef OPENSSL_NO_ENGINE ++ {"set_engine", openssl_ssl_ctx_set_engine}, ++#endif + {"verify_mode", openssl_ssl_ctx_verify_mode }, +- {"set_cert_verify", openssl_ssl_ctx_set_cert_verify}, +- {"set_servername_callback", openssl_ssl_ctx_set_servername_callback}, ++ {"set_cert_verify", openssl_ssl_ctx_set_cert_verify}, + + {"verify_depth", openssl_ssl_ctx_verify_depth}, ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + {"set_tmp", openssl_ssl_ctx_set_tmp}, ++#endif + {"flush_sessions", openssl_ssl_ctx_flush_sessions}, + {"session", openssl_ssl_ctx_sessions}, + {"session_cache_mode", openssl_session_cache_mode }, ++ {"set_servername_callback", openssl_ssl_ctx_set_servername_callback }, + + {"__gc", openssl_ssl_ctx_gc}, + {"__tostring", auxiliar_tostring}, +@@ -1015,30 +1303,26 @@ SL_SESSION *(*SSL_CTX_sess_get_get_cb(SS + SSL_SESSION *session; + */ + +- +-static int openssl_ssl_session_new(lua_State*L) ++/*** ++get peer certificate verify result ++@function getpeerverification ++@treturn boolean true for success ++@treturn table all certificate in chains verify result ++ preverify_ok as boolean verify result ++ error as number error code ++ error_string as string error message ++ error_depth as number verify depth ++ current_cert as x509 certificate to verified ++*/ ++static int openssl_ssl_getpeerverification(lua_State *L) + { +- SSL_SESSION *ss = SSL_SESSION_new(); +- PUSH_OBJECT(ss, "openssl.ssl_session"); +- return 1; +-} ++ long err; ++ SSL* ssl = CHECK_OBJECT(1, SSL, "openssl.ssl"); + +-static int openssl_ssl_session_read(lua_State*L) +-{ +- BIO *in = load_bio_object(L, 1); +- SSL_SESSION* ss = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL); +- if (!ss) +- { +- BIO_reset(in); +- ss = d2i_SSL_SESSION_bio(in, NULL); +- } +- BIO_free(in); +- if (ss) +- { +- PUSH_OBJECT(ss, "openssl.ssl_session"); +- return 1; +- } +- return openssl_pushresult(L, 0); ++ err = SSL_get_verify_result(ssl); ++ lua_pushboolean(L, err == X509_V_OK); ++ openssl_valueget(L, ssl, "verify_cert"); ++ return 2; + } + + static int openssl_ssl_session_time(lua_State*L) +@@ -1165,8 +1449,23 @@ static luaL_Reg ssl_session_funcs[] = + + + /***************************SSL**********************************/ ++/*** ++openssl.ssl object ++All SSL object IO operation methods(connect, accept, handshake, read, ++peek or write) return nil or false when fail or error. ++When nil returned, it followed by 'ssl' or 'syscall', means SSL layer or ++system layer error. When false returned, it followed by number 0, ++'want_read','want_write','want_x509_lookup','want_connect','want_accept'. ++Numnber 0 means SSL connection closed, others means you should do some ++SSL operation. ++@type ssl ++*/ + +-/* need more think */ ++/*** ++reset ssl object to allow another connection ++@function clear ++@treturn boolean result true for success ++*/ + static int openssl_ssl_clear(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1174,6 +1473,13 @@ static int openssl_ssl_clear(lua_State*L + return 1; + } + ++/*** ++tell ssl use private key and certificate, and check private key ++@function use ++@tparam evp_pkey pkey ++@tparam[opt] x509 cert ++@treturn boolean result return true for ok, or nil followed by errmsg and errval ++*/ + static int openssl_ssl_use(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1181,7 +1487,6 @@ static int openssl_ssl_use(lua_State*L) + EVP_PKEY* pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); + int ret; + +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 3, "must be private key"); + ret = SSL_use_PrivateKey(s, pkey); + if (ret == 1) + { +@@ -1194,6 +1499,12 @@ static int openssl_ssl_use(lua_State*L) + return openssl_pushresult(L, ret); + } + ++/*** ++get peer certificate and certificate chains ++@function peer ++@treturn[1] x509 certificate ++@treturn[1] sk_of_x509 chains of peer ++*/ + static int openssl_ssl_peer(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1217,6 +1528,12 @@ static int openssl_ssl_gc(lua_State*L) + return 0; + } + ++/*** ++get want to do ++@function want ++@treturn[1] string 'nothing', 'reading', 'writing', 'x509_lookup' ++@treturn[1] number state want ++*/ + static int openssl_ssl_want(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1235,7 +1552,12 @@ static int openssl_ssl_want(lua_State*L) + lua_pushinteger(L, st); + return 2; + } +-#ifndef LIBRESSL_VERSION_NUMBER ++#if !defined(OPENSSL_NO_COMP) && !defined(LIBRESSL_VERSION_NUMBER) ++/*** ++get current compression name ++@function current_compression ++@treturn string ++*/ + static int openssl_ssl_current_compression(lua_State *L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1248,6 +1570,11 @@ static int openssl_ssl_current_compressi + } + #endif + ++/*** ++get current cipher info ++@function current_cipher ++@treturn table include name,version,id,bits,algbits and description ++*/ + static int openssl_ssl_current_cipher(lua_State *L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1276,6 +1603,11 @@ static int openssl_ssl_current_cipher(lu + return 0; + } + ++/*** ++get number of bytes available inside SSL fro immediate read ++@function pending ++@treturn number ++*/ + static int openssl_ssl_pending(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1330,6 +1662,11 @@ static int openssl_ssl_pushresult(lua_St + } + } + ++/*** ++get socket fd of ssl ++@function getfd ++@treturn number fd ++*/ + static int openssl_ssl_getfd(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1337,6 +1674,33 @@ static int openssl_ssl_getfd(lua_State*L + return 1; + } + ++/*** ++get value according to arg ++@function get ++@tparam string arg ++
certificate: return SSL certificates ++
fd: return file or network connect fd ++
rfd: ++
wfd: ++
client_CA_list ++
read_ahead: -> boolean ++
shared_ciphers: string ++
cipher_list -> string ++
verify_mode: number ++
verify_depth ++
state_string ++
state_string_long ++
rstate_string ++
rstate_string_long ++
iversion ++
version ++
default_timeout, ++
certificates ++
verify_result ++
state ++
state_string ++@return according to arg ++*/ + static int openssl_ssl_get(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1429,7 +1793,7 @@ static int openssl_ssl_get(lua_State*L) + } + else if (strcmp(what, "state") == 0) + { +- lua_pushinteger(L, SSL_state(s)); ++ lua_pushinteger(L, SSL_get_state(s)); + } + else if (strcmp(what, "hostname") == 0) + { +@@ -1441,6 +1805,25 @@ static int openssl_ssl_get(lua_State*L) + return top - 1; + } + ++/*** ++set value according to arg ++@function set ++@tparam string arg ++
certificate: return SSL certificates ++
fd: return file or network connect fd ++
rfd: ++
wfd: ++
client_CA: ++
read_ahead: ++
cipher_list: ++
verify_depth: ++
purpose: ++
trust: ++
verify_result: ++
hostname: ++@param value val type accroding to arg ++@return value ++*/ + static int openssl_ssl_set(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1482,7 +1865,6 @@ static int openssl_ssl_set(lua_State*L) + int depth = luaL_checkint(L, i + 1); + SSL_set_verify_depth(s, depth); + } +- + else if (strcmp(what, "purpose") == 0) + { + //FIX +@@ -1505,14 +1887,6 @@ static int openssl_ssl_set(lua_State*L) + const char* hostname = luaL_checkstring(L, i + 1); + SSL_set_tlsext_host_name(s, hostname); + } +- +-#if OPENSSL_VERSION_NUMBER > 0x10000000L +- else if (strcmp(what, "state") == 0) +- { +- int l = luaL_checkint(L, 2); +- SSL_set_state(s, l); +- } +-#endif + else + luaL_argerror(L, i, "don't understand"); + +@@ -1522,6 +1896,12 @@ static int openssl_ssl_set(lua_State*L) + return 0; + } + ++/*** ++do ssl server accept ++@function accept ++@treturn boolean true for success ++@treturn string fail reason ++*/ + static int openssl_ssl_accept(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1529,6 +1909,12 @@ static int openssl_ssl_accept(lua_State* + return openssl_ssl_pushresult(L, s, ret); + } + ++/*** ++do ssl client connect ++@function connect ++@treturn boolean true for success ++@treturn string fail reasion ++*/ + static int openssl_ssl_connect(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1536,6 +1922,13 @@ static int openssl_ssl_connect(lua_State + return openssl_ssl_pushresult(L, s, ret); + } + ++/*** ++do ssl read ++@function read ++@tparam[opt=4096] number length to read ++@treturn string data, nil or false for fail ++@treturn string fail reason ++*/ + static int openssl_ssl_read(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1558,6 +1951,13 @@ static int openssl_ssl_read(lua_State*L) + return ret; + } + ++/*** ++do ssl peak, data can be read again ++@function peek ++@tparam[opt=4096] number length to read ++@treturn string data, nil or false for fail ++@treturn string fail reason ++*/ + static int openssl_ssl_peek(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1581,6 +1981,13 @@ static int openssl_ssl_peek(lua_State*L) + return ret; + } + ++/*** ++do ssl write ++@function write ++@tparam string data ++@treturn number count of bytes write successfully ++@treturn string fail reason ++*/ + static int openssl_ssl_write(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1598,6 +2005,12 @@ static int openssl_ssl_write(lua_State*L + } + } + ++/*** ++do ssl handshake, support both server and client side ++@function handshake ++@treturn boolean true for success ++@treturn string fail reasion ++*/ + static int openssl_ssl_do_handshake(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1605,6 +2018,12 @@ static int openssl_ssl_do_handshake(lua_ + return openssl_ssl_pushresult(L, s, ret); + } + ++/*** ++do ssl renegotiate ++@function renegotiate ++@treturn boolean true for success ++@treturn string fail reasion ++*/ + static int openssl_ssl_renegotiate(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1620,6 +2039,19 @@ static int openssl_ssl_renegotiate_abbre + return openssl_ssl_pushresult(L, s, ret); + } + #endif ++ ++/*** ++get ssl renegotiate_pending ++@function renegotiate_pending ++@treturn boolean true for success ++@treturn string fail reasion ++*/ ++/*** ++do ssl renegotiate_pending ++@function renegotiate_pending ++@treturn boolean true for success ++@treturn string fail reasion ++*/ + static int openssl_ssl_renegotiate_pending(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1627,6 +2059,23 @@ static int openssl_ssl_renegotiate_pendi + return openssl_ssl_pushresult(L, s, ret); + } + ++/*** ++shutdown ssl connection with quite or noquite mode ++@function shutdown ++@tparam boolean mode ++@treturn boolean if mode is true, return true or false for quite ++@treturn string if mode is false, return 'read' or 'write' for shutdown direction ++*/ ++/*** ++shutdown SSL connection ++@function shutdown ++*/ ++/*** ++shutdown ssl connect with special mode, disable read or write, ++enable or disable quite shutdown ++@function shutdown ++@tparam string mode support 'read','write', 'quite', 'noquite' ++*/ + static int openssl_ssl_shutdown(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1674,6 +2123,10 @@ static int openssl_ssl_shutdown(lua_Stat + return 0; + }; + ++/*** ++make ssl to client mode ++@function set_connect_state ++*/ + static int openssl_ssl_set_connect_state(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1681,6 +2134,10 @@ static int openssl_ssl_set_connect_state + return 0; + } + ++/*** ++make ssl to server mode ++@function set_accept_state ++*/ + static int openssl_ssl_set_accept_state(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1688,6 +2145,11 @@ static int openssl_ssl_set_accept_state( + return 0; + } + ++/*** ++duplicate ssl object ++@treturn ssl ++@function dup ++*/ + static int openssl_ssl_dup(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1696,6 +2158,10 @@ static int openssl_ssl_dup(lua_State*L) + return 1; + } + ++/*** ++get ssl session resused ++@function session_reused ++*/ + static int openssl_ssl_session_reused(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1722,6 +2188,17 @@ static int openssl_ssl_set_debug(lua_Sta + #endif + + #if OPENSSL_VERSION_NUMBER >= 0x0090819fL ++/*** ++get ssl_ctx associate with current ssl ++@function ctx ++@treturn ssl_ctx ++*/ ++/*** ++set ssl_ctx associate to current ssl ++@function ctx ++@tparam ssl_ctx ctx ++@treturn ssl_ctx orgine ssl_ctx object ++*/ + static int openssl_ssl_ctx(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1741,7 +2218,18 @@ static int openssl_ssl_ctx(lua_State*L) + } + #endif + +- ++/*** ++get ssl session ++@treturn ssl_session session object ++@function session ++*/ ++/*** ++set ssl session ++@function session ++@tparam string|ssl_session sesion ++ reuse session would speed up ssl handshake ++@treturn boolean result ++*/ + static int openssl_ssl_session(lua_State*L) + { + SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); +@@ -1794,7 +2282,7 @@ static luaL_Reg ssl_funcs[] = + {"getfd", openssl_ssl_getfd}, + + {"current_cipher", openssl_ssl_current_cipher}, +-#ifndef LIBRESSL_VERSION_NUMBER ++#if !defined(OPENSSL_NO_COMP) && !defined(LIBRESSL_VERSION_NUMBER) + {"current_compression", openssl_ssl_current_compression}, + #endif + {"getpeerverification", openssl_ssl_getpeerverification}, +@@ -1834,16 +2322,6 @@ static luaL_Reg ssl_funcs[] = + {NULL, NULL}, + }; + +-static luaL_Reg R[] = +-{ +- {"ctx_new", openssl_ssl_ctx_new }, +- {"alert_string", openssl_ssl_alert_string }, +- +- {"session_new", openssl_ssl_session_new}, +- {"session_read", openssl_ssl_session_read}, +- {NULL, NULL} +-}; +- + int luaopen_ssl(lua_State *L) + { + int i; +@@ -1855,7 +2333,6 @@ int luaopen_ssl(lua_State *L) + auxiliar_newclass(L, "openssl.ssl_session", ssl_session_funcs); + auxiliar_newclass(L, "openssl.ssl", ssl_funcs); + +- + lua_newtable(L); + luaL_setfuncs(L, R, 0); + +@@ -1863,12 +2340,7 @@ int luaopen_ssl(lua_State *L) + lua_pushliteral(L, MYVERSION); + lua_settable(L, -3); + +- for (i = 0; i < sizeof(ssl_options) / sizeof(LuaL_Enum) - 1; i++) +- { +- LuaL_Enum e = ssl_options[i]; +- lua_pushinteger(L, e.val); +- lua_setfield(L, -2, e.name); +- } ++ auxiliar_enumerate(L, -1, ssl_options); + for (i = 0; sVerifyMode_Options[i]; i++) + { + lua_pushinteger(L, iVerifyMode_Options[i]); +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/ssl_options.h luvi-src-v2.7.6/deps/lua-openssl/src/ssl_options.h +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/ssl_options.h 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/ssl_options.h 2019-02-13 11:53:24.321792707 +0100 +@@ -4,7 +4,7 @@ + #include + #include "auxiliar.h" + +-static LuaL_Enum ssl_options[] = ++static LuaL_Enumeration ssl_options[] = + { + #if defined(SSL_OP_ALL) + {"all", SSL_OP_ALL}, +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/th-lock.c luvi-src-v2.7.6/deps/lua-openssl/src/th-lock.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/th-lock.c 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/th-lock.c 2019-02-13 11:53:24.321792707 +0100 +@@ -60,6 +60,7 @@ + #include + #include + #include ++#include + #ifdef OPENSSL_SYS_WIN32 + #include + #endif +@@ -76,25 +77,10 @@ + #include + #endif + #endif +-#include +-#include +-#include +-#include +-#include +-#include + + void CRYPTO_thread_setup(void); + void CRYPTO_thread_cleanup(void); + +-static void irix_locking_callback(int mode, int type, const char *file, int line); +-static void solaris_locking_callback(int mode, int type, const char *file, int line); +-static void win32_locking_callback(int mode, int type, const char *file, int line); +-static void pthreads_locking_callback(int mode, int type, const char *file, int line); +- +-static unsigned long irix_thread_id(void ); +-static unsigned long solaris_thread_id(void ); +-static unsigned long pthreads_thread_id(void ); +- + /* usage: + * CRYPTO_thread_setup(); + * application code +@@ -105,6 +91,8 @@ static unsigned long pthreads_thread_id( + + #ifdef OPENSSL_SYS_WIN32 + ++static void win32_locking_callback(int mode, int type, const char *file, int line); ++ + static HANDLE *lock_cs; + + void CRYPTO_thread_setup(void) +@@ -149,6 +137,9 @@ static void win32_locking_callback(int m + + #ifdef SOLARIS + ++static void solaris_locking_callback(int mode, int type, const char *file, int line); ++static unsigned long solaris_thread_id(void ); ++ + #define USE_MUTEX + + #ifdef USE_MUTEX +@@ -246,6 +237,10 @@ unsigned long solaris_thread_id(void) + #endif /* SOLARIS */ + + #ifdef IRIX ++ ++static void irix_locking_callback(int mode, int type, const char *file, int line); ++static unsigned long irix_thread_id(void ); ++ + /* I don't think this works..... */ + + static usptr_t *arena; +@@ -316,6 +311,10 @@ unsigned long irix_thread_id(void) + /* Linux and a few others */ + #ifdef PTHREADS + #ifndef OPENSSL_SYS_WIN32 ++ ++static void pthreads_locking_callback(int mode, int type, const char *file, int line); ++static unsigned long pthreads_thread_id(void ); ++ + static pthread_mutex_t *lock_cs; + static long *lock_count; + +@@ -335,7 +334,7 @@ void CRYPTO_thread_setup(void) + CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); + } + +-void thread_cleanup(void) ++void CRYPTO_thread_cleanup(void) + { + int i; + +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/util.c luvi-src-v2.7.6/deps/lua-openssl/src/util.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/util.c 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/util.c 2019-02-13 11:53:24.321792707 +0100 +@@ -1,6 +1,6 @@ + #include "private.h" + +-int openssl_newvalue(lua_State*L, void*p) ++int openssl_newvalue(lua_State*L,const void*p) + { + lua_rawgetp(L, LUA_REGISTRYINDEX, p); + if (lua_isnil(L, -1)) +@@ -14,14 +14,14 @@ int openssl_newvalue(lua_State*L, void*p + return 0; + } + +-int openssl_freevalue(lua_State*L, void*p) ++int openssl_freevalue(lua_State*L, const void*p) + { + lua_pushnil(L); + lua_rawsetp(L, LUA_REGISTRYINDEX, p); + return 0; + } + +-int openssl_setvalue(lua_State*L, void*p, const char*field) ++int openssl_valueset(lua_State*L, const void*p, const char*field) + { + lua_rawgetp(L, LUA_REGISTRYINDEX, p); + lua_pushvalue(L, -2); +@@ -31,7 +31,7 @@ int openssl_setvalue(lua_State*L, void*p + return 0; + } + +-int openssl_getvalue(lua_State*L, void*p, const char*field) ++int openssl_valueget(lua_State*L, const void*p, const char*field) + { + lua_rawgetp(L, LUA_REGISTRYINDEX, p); + if (!lua_isnil(L, -1)) +@@ -39,10 +39,43 @@ int openssl_getvalue(lua_State*L, void*p + lua_getfield(L, -1, field); + lua_remove(L, -2); + } ++ return lua_type(L, -1); ++} ++ ++int openssl_valueseti(lua_State*L, const void*p, int i) ++{ ++ lua_rawgetp(L, LUA_REGISTRYINDEX, p); ++ lua_pushvalue(L, -2); ++ lua_remove(L, -3); ++ lua_rawseti(L, -2, i); ++ lua_pop(L, 1); + return 0; + } + +-int openssl_refrence(lua_State*L, void*p, int op) ++int openssl_valuegeti(lua_State*L, const void*p, int i) ++{ ++ lua_rawgetp(L, LUA_REGISTRYINDEX, p); ++ if (!lua_isnil(L, -1)) ++ { ++ lua_rawgeti(L, -1, i); ++ lua_remove(L, -2); ++ } ++ return lua_type(L, -1); ++} ++ ++size_t openssl_valuelen(lua_State*L, const void*p) ++{ ++ size_t s = 0; ++ lua_rawgetp(L, LUA_REGISTRYINDEX, p); ++ if (!lua_isnil(L, -1)) ++ { ++ s = lua_rawlen(L, -1); ++ } ++ lua_pop(L, 1); ++ return s; ++} ++ ++int openssl_refrence(lua_State*L, const void*p, int op) + { + int ref; + lua_rawgetp(L, LUA_REGISTRYINDEX, p); +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/x509.c luvi-src-v2.7.6/deps/lua-openssl/src/x509.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/x509.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/x509.c 2019-02-13 11:53:24.321792707 +0100 +@@ -1,9 +1,12 @@ +-/*=========================================================================*\ +-* x509.c +-* x509 modules for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ ++/*** ++x509 modules for lua-openssl binding ++create and manage x509 certificate ++@module x509 ++@usage ++ x509 = require'openssl'.x509 ++*/ ++ ++ + #include "openssl.h" + #include "private.h" + #define CRYPTO_LOCK_REF +@@ -13,21 +16,326 @@ + #define MYVERSION MYNAME " library for " LUA_VERSION " / Nov 2014 / "\ + "based on OpenSSL " SHLIB_VERSION_NUMBER + +-int openssl_push_x509_algor(lua_State*L, const X509_ALGOR* alg) ++static int openssl_push_purpose(lua_State*L, X509_PURPOSE* purpose) + { + lua_newtable(L); +- openssl_push_asn1object(L, alg->algorithm); +- lua_setfield(L, -2, "algorithm"); +- if (alg->parameter) ++ ++ AUXILIAR_SET(L, -1, "purpose", purpose->purpose, integer); ++ AUXILIAR_SET(L, -1, "trust", purpose->trust, integer); ++ AUXILIAR_SET(L, -1, "flags", purpose->flags, integer); ++ ++ AUXILIAR_SET(L, -1, "name", purpose->name, string); ++ AUXILIAR_SET(L, -1, "sname", purpose->sname, string); ++ ++ return 1; ++}; ++ ++/*** ++return all supported purpose as table ++@function purpose ++@treturn table ++*/ ++/* ++get special purpose info as table ++@function purpose ++@tparam number|string purpose id or short name ++@treturn table ++*/ ++static int openssl_x509_purpose(lua_State*L) ++{ ++ if (lua_isnoneornil(L, 1)) ++ { ++ int count = X509_PURPOSE_get_count(); ++ int i; ++ lua_newtable(L); ++ for (i = 0; i < count; i++) ++ { ++ X509_PURPOSE* purpose = X509_PURPOSE_get0(i); ++ openssl_push_purpose(L, purpose); ++ lua_rawseti(L, -2, i + 1); ++ } ++ return 1; ++ } ++ else if (lua_isnumber(L, 1)) ++ { ++ int idx = X509_PURPOSE_get_by_id(lua_tointeger(L, 1)); ++ if (idx >= 0) ++ { ++ X509_PURPOSE* purpose = X509_PURPOSE_get0(idx); ++ openssl_push_purpose(L, purpose); ++ } ++ else ++ lua_pushnil(L); ++ return 1; ++ } ++ else if (lua_isstring(L, 1)) ++ { ++ char* name = (char*)lua_tostring(L, 1); ++ int idx = X509_PURPOSE_get_by_sname(name); ++ if (idx >= 0) ++ { ++ X509_PURPOSE* purpose = X509_PURPOSE_get0(idx); ++ openssl_push_purpose(L, purpose); ++ } ++ else ++ lua_pushnil(L); ++ return 1; ++ } ++ return 0; ++}; ++ ++static const char* usage_mode[] = ++{ ++ "standard", ++ "netscape", ++ "extend", ++ NULL ++}; ++ ++/*** ++get support certtypes ++@function certtypes ++@tparam[opt='standard'] string type support 'standard','netscape','extend' ++@treturn table if type is 'standard' or 'netscape', contains node with {lname=...,sname=...,bitname=...}, ++ if type is 'extend', contains node with {lname=...,sname=...,nid=...} ++*/ ++static int openssl_x509_certtypes(lua_State*L) ++{ ++ int mode = luaL_checkoption(L, 1, "standard", usage_mode); ++ int i; ++ const BIT_STRING_BITNAME* bitname; ++ ++ switch (mode) ++ { ++ case 0: ++ { ++ const static BIT_STRING_BITNAME key_usage_type_table[] = ++ { ++ {0, "Digital Signature", "digitalSignature"}, ++ {1, "Non Repudiation", "nonRepudiation"}, ++ {2, "Key Encipherment", "keyEncipherment"}, ++ {3, "Data Encipherment", "dataEncipherment"}, ++ {4, "Key Agreement", "keyAgreement"}, ++ {5, "Certificate Sign", "keyCertSign"}, ++ {6, "CRL Sign", "cRLSign"}, ++ {7, "Encipher Only", "encipherOnly"}, ++ {8, "Decipher Only", "decipherOnly"}, ++ { -1, NULL, NULL} ++ }; ++ lua_newtable(L); ++ for (i = 0, bitname = &key_usage_type_table[i]; bitname->bitnum != -1; i++, bitname = &key_usage_type_table[i]) ++ { ++ openssl_push_bit_string_bitname(L, bitname); ++ lua_rawseti(L, -2, i + 1); ++ } ++ return 1; ++ ++ } ++ case 1: + { +- openssl_push_asn1type(L, alg->parameter); +- lua_setfield(L, -2, "parameter"); ++ const static BIT_STRING_BITNAME ns_cert_type_table[] = ++ { ++ {0, "SSL Client", "client"}, ++ {1, "SSL Server", "server"}, ++ {2, "S/MIME", "email"}, ++ {3, "Object Signing", "objsign"}, ++ {4, "Unused", "reserved"}, ++ {5, "SSL CA", "sslCA"}, ++ {6, "S/MIME CA", "emailCA"}, ++ {7, "Object Signing CA", "objCA"}, ++ { -1, NULL, NULL} ++ }; ++ lua_newtable(L); ++ for (i = 0, bitname = &ns_cert_type_table[i]; bitname->bitnum != -1; i++, bitname = &ns_cert_type_table[i]) ++ { ++ openssl_push_bit_string_bitname(L, bitname); ++ lua_rawseti(L, -2, i + 1); ++ } ++ return 1; + } ++ case 2: ++ { ++ static const int ext_nids[] = ++ { ++ NID_server_auth, ++ NID_client_auth, ++ NID_email_protect, ++ NID_code_sign, ++ NID_ms_sgc, ++ NID_ns_sgc, ++ NID_OCSP_sign, ++ NID_time_stamp, ++ NID_dvcs, ++ NID_anyExtendedKeyUsage ++ }; ++ int count = sizeof(ext_nids) / sizeof(int); ++ int nid; ++ lua_newtable(L); ++ for (i = 0; i < count; i++) ++ { ++ nid = ext_nids[i]; ++ lua_newtable(L); ++ lua_pushstring(L, OBJ_nid2ln(nid)); ++ lua_setfield(L, -2, "lname"); ++ lua_pushstring(L, OBJ_nid2sn(nid)); ++ lua_setfield(L, -2, "sname"); ++ lua_pushinteger(L, nid); ++ lua_setfield(L, -2, "nid"); ++ lua_rawseti(L, -2, i + 1); ++ }; ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++/*** ++get certificate verify result string message ++@function verify_cert_error_string ++@tparam number verify_result ++@treturn string result message ++*/ ++static int openssl_verify_cert_error_string(lua_State*L) ++{ ++ int v = luaL_checkint(L, 1); ++ const char*s = X509_verify_cert_error_string(v); ++ lua_pushstring(L, s); + return 1; ++} ++ ++/*** ++read x509 from string or bio input ++@function read ++@tparam bio|string input input data ++@tparam[opt='auto'] string format support 'auto','pem','der' ++@treturn x509 certificate object ++*/ ++static LUA_FUNCTION(openssl_x509_read) ++{ ++ X509 *cert = NULL; ++ BIO *in = load_bio_object(L, 1); ++ int fmt = luaL_checkoption(L, 2, "auto", format); ++ if (fmt == FORMAT_AUTO) ++ { ++ fmt = bio_is_der(in) ? FORMAT_DER : FORMAT_PEM; ++ } ++ ++ if (fmt == FORMAT_DER) ++ { ++ cert = d2i_X509_bio(in, NULL); ++ } ++ else if (fmt == FORMAT_PEM) ++ { ++ cert = PEM_read_bio_X509(in, NULL, NULL, NULL); ++ } ++ ++ BIO_free(in); ++ ++ if (cert) ++ { ++ PUSH_OBJECT(cert, "openssl.x509"); ++ return 1; ++ } ++ return openssl_pushresult(L, 0); ++} ++ ++/*** ++create or generate a new x509 object. ++@function new ++@tparam[opt] openssl.bn serial serial number ++@tparam[opt] x509_req csr,copy x509_name, pubkey and extension to new object ++@tparam[opt] x509_name subject subject name set to x509_req ++@tparam[opt] stack_of_x509_extension extensions add to x509 ++@tparam[opt] stack_of_x509_attribute attributes add to x509 ++@treturn x509 certificate object ++*/ ++static int openssl_x509_new(lua_State* L) ++{ ++ int i = 1; ++ int ret = 1; ++ int n = lua_gettop(L); ++ X509 *x = X509_new(); ++ ++ ret = X509_set_version(x, 2); ++ if (ret == 1 && ( ++ auxiliar_getclassudata(L, "openssl.bn", i) || ++ lua_isstring(L, i) || lua_isnumber(L, i) ++ )) ++ { ++ BIGNUM *bn = BN_get(L, i); ++ ASN1_INTEGER* ai = BN_to_ASN1_INTEGER(bn, NULL); ++ BN_free(bn); ++ ret = X509_set_serialNumber(x, ai); ++ ASN1_INTEGER_free(ai); ++ i++; ++ } ++ ++ for (; i <= n; i++) ++ { ++ if (ret == 1 && auxiliar_getclassudata(L, "openssl.x509_req", i)) ++ { ++ X509_REQ* csr = CHECK_OBJECT(i, X509_REQ, "openssl.x509_req"); ++ X509_NAME* xn = X509_REQ_get_subject_name(csr); ++ ret = X509_set_subject_name(x, xn); ++ ++ if (ret == 1) ++ { ++ STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(csr); ++ int j, n1; ++ n1 = sk_X509_EXTENSION_num(exts); ++ for (j = 0; ret == 1 && j < n1; j++) ++ { ++ ret = X509_add_ext(x, sk_X509_EXTENSION_value(exts, j), j); ++ } ++ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); ++ } ++ if (ret == 1) ++ { ++ EVP_PKEY* pkey = X509_REQ_get_pubkey(csr); ++ ret = X509_set_pubkey(x, pkey); ++ EVP_PKEY_free(pkey); ++ } ++ i++; ++ }; ++ ++ if (ret == 1 && auxiliar_getclassudata(L, "openssl.x509_name", i)) ++ { ++ X509_NAME *xn = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name"); ++ ret = X509_set_subject_name(x, xn); ++ i++; ++ } ++ } ++ ++ if (ret == 1) ++ { ++ PUSH_OBJECT(x, "openssl.x509"); ++ return 1; ++ } ++ else ++ { ++ X509_free(x); ++ return openssl_pushresult(L, ret); ++ } ++}; ++ ++static luaL_Reg R[] = ++{ ++ {"new", openssl_x509_new }, ++ {"read", openssl_x509_read }, ++ {"purpose", openssl_x509_purpose }, ++ {"certtypes", openssl_x509_certtypes }, ++ {"verify_cert_error_string", openssl_verify_cert_error_string }, ++ ++ {NULL, NULL} + }; + + int openssl_push_general_name(lua_State*L, const GENERAL_NAME* general_name) + { ++ if (general_name == NULL) ++ { ++ lua_pushnil(L); ++ return 1; ++ } + lua_newtable(L); + + switch (general_name->type) +@@ -137,37 +445,17 @@ static int check_cert(X509_STORE *ca, X5 + return X509_V_ERR_OUT_OF_MEM; + } + +-static LUA_FUNCTION(openssl_x509_read) +-{ +- X509 *cert = NULL; +- BIO *in = load_bio_object(L, 1); +- int fmt = luaL_checkoption(L, 2, "auto", format); +- if (fmt == FORMAT_AUTO) +- { +- fmt = bio_is_der(in) ? FORMAT_DER : FORMAT_PEM; +- } +- +- if (fmt == FORMAT_DER) +- { +- cert = d2i_X509_bio(in, NULL); +- BIO_reset(in); +- } +- else if (fmt == FORMAT_PEM) +- { +- cert = PEM_read_bio_X509(in, NULL, NULL, NULL); +- BIO_reset(in); +- } +- +- BIO_free(in); +- +- if (cert) +- { +- PUSH_OBJECT(cert, "openssl.x509"); +- return 1; +- } +- return openssl_pushresult(L, 0); +-} +- ++/*** ++openssl.x509 object ++@type x509 ++*/ ++/*** ++export x509_req to string ++@function export ++@tparam[opt='pem'] string format, 'der' or 'pem' default ++@tparam[opt='true'] boolean noext not export extension ++@treturn string ++*/ + static LUA_FUNCTION(openssl_x509_export) + { + X509 *cert = CHECK_OBJECT(1, X509, "openssl.x509"); +@@ -213,19 +501,25 @@ static LUA_FUNCTION(openssl_x509_export) + return 1; + }; + +- ++/*** ++parse x509 object as table ++@function parse ++@tparam[opt=true] shortname default will use short object name ++@treturn table result which all x509 information ++*/ + static LUA_FUNCTION(openssl_x509_parse) + { + int i; + X509 * cert = CHECK_OBJECT(1, X509, "openssl.x509"); + X509_ALGOR* alg = 0; + lua_newtable(L); +- ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + if (cert->name) + { + AUXILIAR_SET(L, -1, "name", cert->name, string); + } + AUXILIAR_SET(L, -1, "valid", cert->valid, boolean); ++#endif + AUXILIAR_SET(L, -1, "version", X509_get_version(cert), integer); + + openssl_push_xname_asobject(L, X509_get_subject_name(cert)); +@@ -238,16 +532,31 @@ static LUA_FUNCTION(openssl_x509_parse) + AUXILIAR_SET(L, -1, "hash", buf, string); + } + +- PUSH_ASN1_INTEGER(L, cert->cert_info->serialNumber); ++ PUSH_ASN1_INTEGER(L, X509_get0_serialNumber(cert)); + lua_setfield(L, -2, "serialNumber"); ++ + PUSH_ASN1_TIME(L, X509_get_notBefore(cert)); + lua_setfield(L, -2, "notBefore"); + PUSH_ASN1_TIME(L, X509_get_notAfter(cert)); + lua_setfield(L, -2, "notAfter"); + +- alg = X509_ALGOR_dup(cert->sig_alg); +- PUSH_OBJECT(alg, "openssl.x509_algor"); +- lua_setfield(L, -2, "sig_alg"); ++ { ++ CONSTIFY_X509_get0 X509_ALGOR *palg = NULL; ++ CONSTIFY_X509_get0 ASN1_BIT_STRING *psig = NULL; ++ ++ X509_get0_signature(&psig, &palg, cert); ++ if (palg != NULL) ++ { ++ alg = X509_ALGOR_dup((X509_ALGOR*)palg); ++ PUSH_OBJECT(alg, "openssl.x509_algor"); ++ lua_setfield(L, -2, "sig_alg"); ++ } ++ if (psig != NULL) ++ { ++ lua_pushlstring(L, (const char *)psig->data, psig->length); ++ lua_setfield(L, -2, "sig"); ++ } ++ } + + { + int l = 0; +@@ -312,6 +621,17 @@ static LUA_FUNCTION(openssl_x509_free) + return 0; + } + ++/*** ++get public key of x509 ++@function pubkey ++@treturn evp_pkey public key ++*/ ++/*** ++set public key of x509 ++@function pubkey ++@tparam evp_pkey pubkey public key set to x509 ++@treturn boolean result, true for success ++*/ + static LUA_FUNCTION(openssl_x509_public_key) + { + X509 *cert = CHECK_OBJECT(1, X509, "openssl.x509"); +@@ -329,6 +649,7 @@ static LUA_FUNCTION(openssl_x509_public_ + } + } + ++#if 0 + static int verify_cb(int ok, X509_STORE_CTX *ctx) + { + int err; +@@ -360,14 +681,31 @@ static int verify_cb(int ok, X509_STORE_ + return 1; + } + } ++#endif + ++/*** ++check x509 with ca certchian and option purpose ++purpose can be one of: ssl_client, ssl_server, ns_ssl_server, smime_sign, smime_encrypt, crl_sign, any, ocsp_helper, timestamp_sign ++@function check ++@tparam x509_store cacerts ++@tparam x509_store untrusted certs containing a bunch of certs that are not trusted but may be useful in validating the certificate. ++@tparam[opt] string purpose to check supported ++@treturn boolean result true for check pass ++@treturn integer verify result ++@see verify_cert_error_string ++*/ ++/*** ++check x509 with evp_pkey ++@function check ++@tparam evp_pkey pkey private key witch match with x509 pubkey ++@treturn boolean result true for check pass ++*/ + static LUA_FUNCTION(openssl_x509_check) + { + X509 * cert = CHECK_OBJECT(1, X509, "openssl.x509"); +- if (auxiliar_isclass(L, "openssl.evp_pkey", 2)) ++ if (auxiliar_getclassudata(L, "openssl.evp_pkey", 2)) + { + EVP_PKEY * key = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); +- luaL_argcheck(L, openssl_pkey_is_private(key), 2, "must be private key"); + lua_pushboolean(L, X509_check_private_key(cert, key)); + return 1; + } +@@ -375,8 +713,20 @@ static LUA_FUNCTION(openssl_x509_check) + { + X509_STORE* store = CHECK_OBJECT(2, X509_STORE, "openssl.x509_store"); + STACK_OF(X509)* untrustedchain = lua_isnoneornil(L, 3) ? NULL : openssl_sk_x509_fromtable(L, 3); +- int purpose = lua_isnone(L, 4) ? 0 : X509_PURPOSE_get_by_sname((char*)luaL_optstring(L, 4, "any")); ++ int purpose = 0; + int ret = 0; ++ if (!lua_isnone(L, 4)) ++ { ++ int purpose_id = X509_PURPOSE_get_by_sname((char*)luaL_optstring(L, 4, "any")); ++ if (purpose_id >= 0) ++ { ++ X509_PURPOSE* ppurpose = X509_PURPOSE_get0(purpose_id); ++ if (ppurpose) ++ { ++ purpose = ppurpose->purpose; ++ } ++ } ++ } + #if 0 + X509_STORE_set_verify_cb_func(store, verify_cb); + #endif +@@ -388,8 +738,73 @@ static LUA_FUNCTION(openssl_x509_check) + } + } + ++#if OPENSSL_VERSION_NUMBER > 0x10002000L ++/*** ++check x509 for host (only for openssl 1.0.2 or greater) ++@function check_host ++@tparam string host hostname to check for match match with x509 subject ++@treturn boolean result true if host is present and matches the certificate ++*/ ++static LUA_FUNCTION(openssl_x509_check_host) ++{ ++ X509 * cert = CHECK_OBJECT(1, X509, "openssl.x509"); ++ if (lua_isstring(L, 2)) ++ { ++ const char *hostname = lua_tostring(L, 2); ++ lua_pushboolean(L, X509_check_host(cert, hostname, strlen(hostname), 0, NULL)); ++ } ++ else ++ { ++ lua_pushboolean(L, 0); ++ } ++ return 1; ++} ++/*** ++check x509 for email address (only for openssl 1.0.2 or greater) ++@tparam string email to check for match match with x509 subject ++@treturn boolean result true if host is present and matches the certificate ++@function check_email ++*/ ++static LUA_FUNCTION(openssl_x509_check_email) ++{ ++ X509 * cert = CHECK_OBJECT(1, X509, "openssl.x509"); ++ if (lua_isstring(L, 2)) ++ { ++ const char *email = lua_tostring(L, 2); ++ lua_pushboolean(L, X509_check_email(cert, email, strlen(email), 0)); ++ } ++ else ++ { ++ lua_pushboolean(L, 0); ++ } ++ return 1; ++} ++ ++/*** ++check x509 for ip address (ipv4 or ipv6, only for openssl 1.0.2 or greater) ++@function check_ip_asc ++@tparam string ip to check for match match with x509 subject ++@treturn boolean result true if host is present and matches the certificate ++*/ ++static LUA_FUNCTION(openssl_x509_check_ip_asc) ++{ ++ X509 * cert = CHECK_OBJECT(1, X509, "openssl.x509"); ++ if (lua_isstring(L, 2)) ++ { ++ const char *ip_asc = lua_tostring(L, 2); ++ lua_pushboolean(L, X509_check_ip_asc(cert, ip_asc, 0)); ++ } ++ else ++ { ++ lua_pushboolean(L, 0); ++ } ++ return 1; ++} ++#endif ++ + IMP_LUA_SK(X509, x509) + ++#if 0 + static STACK_OF(X509) * load_all_certs_from_file(BIO *in) + { + STACK_OF(X509) *stack = sk_X509_new_null(); +@@ -417,7 +832,19 @@ static STACK_OF(X509) * load_all_certs_f + } + return stack; + }; ++#endif + ++/*** ++get subject name of x509 ++@function subject ++@treturn x509_name subject name ++*/ ++/*** ++set subject name of x509 ++@function subject ++@tparam x509_name subject ++@treturn boolean result true for success ++*/ + static int openssl_x509_subject(lua_State* L) + { + X509* cert = CHECK_OBJECT(1, X509, "openssl.x509"); +@@ -434,6 +861,19 @@ static int openssl_x509_subject(lua_Stat + } + } + ++/*** ++get issuer name of x509 ++@function issuer ++@tparam[opt=false] boolean asobject, true for return as x509_name object, or as table ++@treturn[1] x509_name issuer ++@treturn[1] table issuer name as table ++*/ ++/*** ++set issuer name of x509 ++@function issuer ++@tparam x509_name name ++@treturn boolean result true for success ++*/ + static int openssl_x509_issuer(lua_State* L) + { + X509* cert = CHECK_OBJECT(1, X509, "openssl.x509"); +@@ -450,13 +890,19 @@ static int openssl_x509_issuer(lua_State + } + } + ++/*** ++get digest of x509 object ++@function digest ++@tparam[opt='sha1'] evp_digest|string md_alg, default use 'sha1' ++@treturn string digest result ++*/ + static int openssl_x509_digest(lua_State* L) + { + unsigned int bytes; + unsigned char buffer[EVP_MAX_MD_SIZE]; + char hex_buffer[EVP_MAX_MD_SIZE * 2]; + X509 *cert = CHECK_OBJECT(1, X509, "openssl.x509"); +- const EVP_MD *digest = lua_isnoneornil(L, 2) ? EVP_sha1() : get_digest(L, 2); ++ const EVP_MD *digest = get_digest(L, 2, "sha256"); + int ret; + if (!digest) + { +@@ -474,6 +920,16 @@ static int openssl_x509_digest(lua_State + return openssl_pushresult(L, ret); + }; + ++/*** ++get notbefore valid time of x509 ++@function notbefore ++@treturn string notbefore time string ++*/ ++/*** ++set notbefore valid time of x509 ++@function notbefore ++@tparam string|number notbefore ++*/ + static int openssl_x509_notbefore(lua_State *L) + { + X509* cert = CHECK_OBJECT(1, X509, "openssl.x509"); +@@ -491,7 +947,7 @@ static int openssl_x509_notbefore(lua_St + at = ASN1_TIME_new(); + ASN1_TIME_set(at, time); + } +- if (lua_isstring(L, 2)) ++ else if (lua_isstring(L, 2)) + { + const char* time = lua_tostring(L, 2); + at = ASN1_TIME_new(); +@@ -504,6 +960,7 @@ static int openssl_x509_notbefore(lua_St + if (at) + { + ret = X509_set_notBefore(cert, at); ++ ASN1_TIME_free(at); + } + else + ret = 0; +@@ -511,6 +968,16 @@ static int openssl_x509_notbefore(lua_St + }; + } + ++/*** ++get notafter valid time of x509 ++@function notafter ++@treturn string notafter time string ++*/ ++/*** ++set notafter valid time of x509 ++@function notafter ++@tparam string|number notafter ++*/ + static int openssl_x509_notafter(lua_State *L) + { + X509* cert = CHECK_OBJECT(1, X509, "openssl.x509"); +@@ -528,7 +995,7 @@ static int openssl_x509_notafter(lua_Sta + at = ASN1_TIME_new(); + ASN1_TIME_set(at, time); + } +- if (lua_isstring(L, 2)) ++ else if (lua_isstring(L, 2)) + { + const char* time = lua_tostring(L, 2); + at = ASN1_TIME_new(); +@@ -541,6 +1008,7 @@ static int openssl_x509_notafter(lua_Sta + if (at) + { + ret = X509_set_notAfter(cert, at); ++ ASN1_TIME_free(at); + } + else + ret = 0; +@@ -548,6 +1016,21 @@ static int openssl_x509_notafter(lua_Sta + } + } + ++/*** ++check x509 valid ++@function validat ++@tparam[opt] number time, default will use now time ++@treturn boolean result true for valid, or for invalid ++@treturn string notbefore ++@treturn string notafter ++*/ ++/*** ++set valid time, notbefore and notafter ++@function validat ++@tparam number notbefore ++@tparam number notafter ++@treturn boolean result, true for success ++*/ + static int openssl_x509_valid_at(lua_State* L) + { + X509* cert = CHECK_OBJECT(1, X509, "openssl.x509"); +@@ -595,42 +1078,76 @@ static int openssl_x509_valid_at(lua_Sta + return 0; + } + ++/*** ++get serial number of x509 ++@function serial ++@tparam[opt=true] boolean asobject ++@treturn[1] bn object ++@treturn[2] string result ++*/ ++/*** ++set serial number of x509 ++@function serial ++@tparam string|number|bn serail ++@treturn boolean result true for success ++*/ + static int openssl_x509_serial(lua_State *L) + { +- BIGNUM *bn; +- ASN1_INTEGER *serial; + X509* cert = CHECK_OBJECT(1, X509, "openssl.x509"); +- +- if (lua_isnone(L, 2) || lua_isboolean(L, 2)) ++ ASN1_INTEGER *serial = X509_get_serialNumber(cert); ++ if (lua_isboolean(L, 2)) + { +- int asobj = lua_isnone(L, 2) ? 0 : lua_toboolean(L, 2); +- serial = X509_get_serialNumber(cert); +- bn = ASN1_INTEGER_to_BN(serial, NULL); ++ int asobj = lua_toboolean(L, 2); + if (asobj) + { +- PUSH_OBJECT(bn, "openssl.bn"); ++ PUSH_ASN1_INTEGER(L, serial); + } + else + { +- char *tmp = BN_bn2hex(bn); +- lua_pushstring(L, tmp); +- BN_free(bn); +- OPENSSL_free(tmp); ++ BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL); ++ PUSH_OBJECT(bn, "openssl.bn"); + } +- return 1; ++ } ++ else if (lua_isnone(L, 2)) ++ { ++ BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL); ++ char *tmp = BN_bn2hex(bn); ++ lua_pushstring(L, tmp); ++ OPENSSL_free(tmp); ++ BN_free(bn); + } + else + { + int ret; +- bn = BN_get(L, 2); +- serial = BN_to_ASN1_INTEGER(bn, NULL); +- BN_free(bn); ++ if (auxiliar_getclassudata(L, "openssl.asn1_string", 2)) ++ { ++ serial = CHECK_OBJECT(2, ASN1_STRING, "openssl.asn1_string"); ++ } ++ else ++ { ++ BIGNUM *bn = BN_get(L, 2); ++ serial = BN_to_ASN1_INTEGER(bn, NULL); ++ BN_free(bn); ++ } ++ luaL_argcheck(L, serial != NULL, 2, "not accept"); + ret = X509_set_serialNumber(cert, serial); + ASN1_INTEGER_free(serial); + return openssl_pushresult(L, ret); + } ++ return 1; + } + ++/*** ++get version number of x509 ++@function version ++@treturn number version of x509 ++*/ ++/*** ++set version number of x509 ++@function version ++@tparam number version ++@treturn boolean result true for result ++*/ + static int openssl_x509_version(lua_State *L) + { + int version; +@@ -650,12 +1167,25 @@ static int openssl_x509_version(lua_Stat + } + } + ++/*** ++get extensions of x509 object ++@function extensions ++@tparam[opt=false] boolean asobject, true for return as stack_of_x509_extension or as table ++@treturn[1] stack_of_x509_extension object when param set true ++@treturn[2] table contain all x509_extension when param set false or nothing ++*/ ++/*** ++set extension of x509 object ++@function extensions ++@tparam stack_of_x509_extension extensions ++@treturn boolean result true for success ++*/ + static int openssl_x509_extensions(lua_State* L) + { +- X509 *peer = CHECK_OBJECT(1, X509, "openssl.x509"); ++ X509 *self = CHECK_OBJECT(1, X509, "openssl.x509"); ++ STACK_OF(X509_EXTENSION) *exts = (STACK_OF(X509_EXTENSION) *)X509_get0_extensions(self); + if (lua_isnone(L, 2)) + { +- STACK_OF(X509_EXTENSION) *exts = peer->cert_info->extensions; + if (exts) + { + openssl_sk_x509_extension_totable(L, exts); +@@ -666,89 +1196,45 @@ static int openssl_x509_extensions(lua_S + } + else + { +- STACK_OF(X509_EXTENSION) *exts = openssl_sk_x509_extension_fromtable(L, 2); +- sk_X509_EXTENSION_pop_free(peer->cert_info->extensions, X509_EXTENSION_free); +- peer->cert_info->extensions = exts; ++ STACK_OF(X509_EXTENSION) *others = (STACK_OF(X509_EXTENSION) *)openssl_sk_x509_extension_fromtable(L, 2); ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ sk_X509_EXTENSION_pop_free(self->cert_info->extensions, X509_EXTENSION_free); ++ self->cert_info->extensions = others; ++#else ++ int i; ++ int n = sk_X509_EXTENSION_num(exts); ++ for (i = 0; i < n; i++) ++ sk_X509_EXTENSION_delete(exts, i); ++ n = sk_X509_EXTENSION_num(others); ++ for (i = 0; i < n; i++) ++ { ++ X509_EXTENSION* ext = sk_X509_EXTENSION_value(others, i); ++ if (exts!=NULL) ++ sk_X509_EXTENSION_push(exts, ext); ++ else ++ X509_add_ext(self, ext, -1); ++ } ++ sk_X509_EXTENSION_free(others); ++#endif + return openssl_pushresult(L, 1); + } + } + +-static int openssl_x509_new(lua_State* L) +-{ +- int i = 1; +- int ret = 1; +- int n = lua_gettop(L); +- X509 *x = X509_new(); +- +- ret = X509_set_version(x, 2); +- if (ret == 1 && ( +- auxiliar_isclass(L, "openssl.bn", i) || +- lua_isstring(L, i) || lua_isnumber(L, i) +- )) +- { +- BIGNUM *bn = BN_get(L, i); +- ASN1_INTEGER* ai = BN_to_ASN1_INTEGER(bn, NULL); +- BN_free(bn); +- ret = X509_set_serialNumber(x, ai); +- ASN1_INTEGER_free(ai); +- i++; +- } +- +- for (; i <= n; i++) +- { +- if (ret == 1 && auxiliar_isclass(L, "openssl.x509_req", i)) +- { +- X509_REQ* csr = CHECK_OBJECT(i, X509_REQ, "openssl.x509_req"); +- X509_NAME* xn = X509_REQ_get_subject_name(csr); +- ret = X509_set_subject_name(x, xn); +- +- if (ret == 1) +- { +- STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(csr); +- int j, n1; +- n1 = sk_X509_EXTENSION_num(exts); +- for (j = 0; ret == 1 && j < n1; j++) +- { +- ret = X509_add_ext(x, sk_X509_EXTENSION_value(exts, j), j); +- } +- sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); +- } +- if (ret == 1) +- { +- EVP_PKEY* pkey = X509_REQ_get_pubkey(csr); +- ret = X509_set_pubkey(x, pkey); +- EVP_PKEY_free(pkey); +- } +- i++; +- }; +- +- if (ret == 1 && auxiliar_isclass(L, "openssl.x509_name", i)) +- { +- X509_NAME *xn = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name"); +- ret = X509_set_subject_name(x, xn); +- i++; +- } +- } +- +- if (ret == 1) +- { +- PUSH_OBJECT(x, "openssl.x509"); +- return 1; +- } +- else +- { +- X509_free(x); +- return openssl_pushresult(L, ret); +- } +-}; +- ++/*** ++sign x509 ++@function sign ++@tparam evp_pkey pkey private key to sign x509 ++@tparam x509|x509_name cacert or cacert x509_name ++@tparam[opt='sha1WithRSAEncryption'] string|md_digest md_alg ++@treturn boolean result true for check pass ++*/ + static int openssl_x509_sign(lua_State*L) + { + X509* x = CHECK_OBJECT(1, X509, "openssl.x509"); +- if (lua_isnoneornil(L, 2) && x->cert_info != NULL) ++ if (lua_isnoneornil(L, 2)) + { + unsigned char *out = NULL; +- int len = i2d_X509_CINF(x->cert_info, &out); ++ int len = i2d_re_X509_tbs(x, &out); + if (len > 0) + { + lua_pushlstring(L, (const char *)out, len); +@@ -757,14 +1243,13 @@ static int openssl_x509_sign(lua_State*L + } + return openssl_pushresult(L, len); + } +- else if (auxiliar_isclass(L, "openssl.evp_pkey", 2)) ++ else if (auxiliar_getclassudata(L, "openssl.evp_pkey", 2)) + { + EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); + const EVP_MD *md; + int ret = 1; + int i = 3; +- luaL_argcheck(L, openssl_pkey_is_private(pkey), 2, "must be private key"); +- if (auxiliar_isclass(L, "openssl.x509_name", 3)) ++ if (auxiliar_getclassudata(L, "openssl.x509_name", 3)) + { + X509_NAME* xn = CHECK_OBJECT(3, X509_NAME, "openssl.x509_name"); + ret = X509_set_issuer_name(x, xn); +@@ -784,9 +1269,7 @@ static int openssl_x509_sign(lua_State*L + + if (ret == 1) + { +- md = lua_isnoneornil(L, i) ? +- EVP_get_digestbyname("sha1") : +- get_digest(L, i); ++ md = get_digest(L, i, "sha256"); + ret = X509_sign(x, pkey, md); + if (ret > 0) + ret = 1; +@@ -798,11 +1281,16 @@ static int openssl_x509_sign(lua_State*L + size_t sig_len; + const char* sig = luaL_checklstring(L, 2, &sig_len); + int nid = openssl_get_nid(L, 3); +- int ret = ASN1_BIT_STRING_set(x->signature, (unsigned char*)sig, (int)sig_len); ++ CONSTIFY_X509_get0 ASN1_BIT_STRING *psig = NULL; ++ CONSTIFY_X509_get0 X509_ALGOR *palg = NULL; ++ int ret; ++ ++ X509_get0_signature(&psig, &palg, x); ++ ret = ASN1_BIT_STRING_set((ASN1_BIT_STRING*)psig, (unsigned char*)sig, (int)sig_len); + if (ret == 1) + { + ASN1_OBJECT *obj = OBJ_nid2obj(nid); +- ret = X509_ALGOR_set0(x->sig_alg, obj, V_ASN1_UNDEF, NULL); ++ ret = X509_ALGOR_set0((X509_ALGOR*)palg, obj, V_ASN1_UNDEF, NULL); + } + return openssl_pushresult(L, ret); + } +@@ -811,22 +1299,31 @@ static int openssl_x509_sign(lua_State*L + static int openssl_x509_verify(lua_State*L) + { + X509* x = CHECK_OBJECT(1, X509, "openssl.x509"); +- if (lua_isnoneornil(L, 2) && x->cert_info != NULL) ++ if (lua_isnoneornil(L, 2)) + { + unsigned char *out = NULL; +- int len = i2d_X509_CINF(x->cert_info, &out); ++ int len = i2d_re_X509_tbs(x, &out); + if (len > 0) + { ++ CONSTIFY_X509_get0 ASN1_BIT_STRING *psig = NULL; ++ CONSTIFY_X509_get0 X509_ALGOR *palg = NULL; ++ + lua_pushlstring(L, (const char *)out, len); + OPENSSL_free(out); +- if (x->signature != NULL) ++ ++ X509_get0_signature(&psig, &palg, x); ++ if (psig != NULL) + { +- lua_pushlstring(L, (const char *)x->signature->data, x->signature->length); ++ lua_pushlstring(L, (const char *)psig->data, psig->length); + } + else + lua_pushnil(L); +- if (x->sig_alg) +- openssl_push_x509_algor(L, x->sig_alg); ++ ++ if (palg) ++ { ++ X509_ALGOR *alg = X509_ALGOR_dup((X509_ALGOR *)palg); ++ PUSH_OBJECT(alg, "openssl.x509_algor"); ++ } + else + lua_pushnil(L); + return 3; +@@ -846,6 +1343,11 @@ static luaL_Reg x509_funcs[] = + {"parse", openssl_x509_parse}, + {"export", openssl_x509_export}, + {"check", openssl_x509_check}, ++#if OPENSSL_VERSION_NUMBER > 0x10002000L ++ {"check_host", openssl_x509_check_host}, ++ {"check_email", openssl_x509_check_email}, ++ {"check_ip_asc", openssl_x509_check_ip_asc}, ++#endif + {"pubkey", openssl_x509_public_key}, + {"version", openssl_x509_version}, + +@@ -868,181 +1370,6 @@ static luaL_Reg x509_funcs[] = + {NULL, NULL}, + }; + +- +-static int openssl_push_purpose(lua_State*L , X509_PURPOSE* purpose) +-{ +- lua_newtable(L); +- +- AUXILIAR_SET(L, -1, "purpose", purpose->purpose, integer); +- AUXILIAR_SET(L, -1, "trust", purpose->trust, integer); +- AUXILIAR_SET(L, -1, "flags", purpose->flags, integer); +- +- AUXILIAR_SET(L, -1, "name", purpose->name, string); +- AUXILIAR_SET(L, -1, "sname", purpose->sname, string); +- +- return 1; +-}; +- +-static int openssl_x509_purpose(lua_State*L) +-{ +- if (lua_isnoneornil(L, 1)) +- { +- int count = X509_PURPOSE_get_count(); +- int i; +- lua_newtable(L); +- for (i = 0; i < count; i++) +- { +- X509_PURPOSE* purpose = X509_PURPOSE_get0(i); +- openssl_push_purpose(L, purpose); +- lua_rawseti(L, -2, i + 1); +- } +- return 1; +- } +- else if (lua_isnumber(L, 1)) +- { +- int idx = X509_PURPOSE_get_by_id(lua_tointeger(L, 1)); +- if (idx >= 0) +- { +- X509_PURPOSE* purpose = X509_PURPOSE_get0(idx); +- openssl_push_purpose(L, purpose); +- } +- else +- lua_pushnil(L); +- return 1; +- } +- else if (lua_isstring(L, 1)) +- { +- char* name = (char*)lua_tostring(L, 1); +- int idx = X509_PURPOSE_get_by_sname(name); +- if (idx >= 0) +- { +- X509_PURPOSE* purpose = X509_PURPOSE_get0(idx); +- openssl_push_purpose(L, purpose); +- } +- else +- lua_pushnil(L); +- return 1; +- } +- return 0; +-}; +- +-static const char* usage_mode[] = +-{ +- "standard", +- "netscape", +- "extend", +- NULL +-}; +- +-static int openssl_x509_certtypes(lua_State*L) +-{ +- int mode = luaL_checkoption(L, 1, "standard", usage_mode); +- int i; +- const BIT_STRING_BITNAME* bitname; +- +- switch (mode) +- { +- case 0: +- { +- const static BIT_STRING_BITNAME key_usage_type_table[] = +- { +- {0, "Digital Signature", "digitalSignature"}, +- {1, "Non Repudiation", "nonRepudiation"}, +- {2, "Key Encipherment", "keyEncipherment"}, +- {3, "Data Encipherment", "dataEncipherment"}, +- {4, "Key Agreement", "keyAgreement"}, +- {5, "Certificate Sign", "keyCertSign"}, +- {6, "CRL Sign", "cRLSign"}, +- {7, "Encipher Only", "encipherOnly"}, +- {8, "Decipher Only", "decipherOnly"}, +- { -1, NULL, NULL} +- }; +- lua_newtable(L); +- for (i = 0, bitname = &key_usage_type_table[i]; bitname->bitnum != -1; i++, bitname = &key_usage_type_table[i]) +- { +- openssl_push_bit_string_bitname(L, bitname); +- lua_rawseti(L, -2, i + 1); +- } +- return 1; +- +- } +- case 1: +- { +- const static BIT_STRING_BITNAME ns_cert_type_table[] = +- { +- {0, "SSL Client", "client"}, +- {1, "SSL Server", "server"}, +- {2, "S/MIME", "email"}, +- {3, "Object Signing", "objsign"}, +- {4, "Unused", "reserved"}, +- {5, "SSL CA", "sslCA"}, +- {6, "S/MIME CA", "emailCA"}, +- {7, "Object Signing CA", "objCA"}, +- { -1, NULL, NULL} +- }; +- lua_newtable(L); +- for (i = 0, bitname = &ns_cert_type_table[i]; bitname->bitnum != -1; i++, bitname = &ns_cert_type_table[i]) +- { +- openssl_push_bit_string_bitname(L, bitname); +- lua_rawseti(L, -2, i + 1); +- } +- return 1; +- } +- case 2: +- { +- static const int ext_nids[] = +- { +- NID_server_auth, +- NID_client_auth, +- NID_email_protect, +- NID_code_sign, +- NID_ms_sgc, +- NID_ns_sgc, +- NID_OCSP_sign, +- NID_time_stamp, +- NID_dvcs, +- NID_anyExtendedKeyUsage +- }; +- int count = sizeof(ext_nids) / sizeof(int); +- int nid; +- lua_newtable(L); +- for (i = 0; i < count; i++) +- { +- nid = ext_nids[i]; +- lua_newtable(L); +- lua_pushstring(L, OBJ_nid2ln(nid)); +- lua_setfield(L, -2, "lname"); +- lua_pushstring(L, OBJ_nid2sn(nid)); +- lua_setfield(L, -2, "sname"); +- lua_pushinteger(L, nid); +- lua_setfield(L, -2, "nid"); +- lua_rawseti(L, -2, i + 1); +- }; +- return 1; +- } +- } +- return 0; +-} +- +-static int openssl_verify_cert_error_string(lua_State*L) +-{ +- int v = luaL_checkint(L, 1); +- const char*s = X509_verify_cert_error_string(v); +- lua_pushstring(L, s); +- return 1; +-} +- +-static luaL_Reg R[] = +-{ +- {"new", openssl_x509_new }, +- {"read", openssl_x509_read }, +- {"purpose", openssl_x509_purpose }, +- {"certtypes", openssl_x509_certtypes }, +- {"verify_cert_error_string", openssl_verify_cert_error_string }, +- +- {NULL, NULL} +-}; +- + int luaopen_x509(lua_State *L) + { + auxiliar_newclass(L, "openssl.x509", x509_funcs); +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/xalgor.c luvi-src-v2.7.6/deps/lua-openssl/src/xalgor.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/xalgor.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/xalgor.c 2019-02-13 11:53:24.321792707 +0100 +@@ -1,10 +1,11 @@ +-/*=========================================================================*\ +-* xalgor.c +-* * x509_algor routines for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ +- ++/*** ++x509.algor module for lua-openssl binding, Provide X509_ALGOR as lua object. ++Sometime when you make CSR,TS or X509, you maybe need to use this. ++ ++@module x509.algor ++@usage ++ algor = require('openssl').x509.algor ++*/ + #include "openssl.h" + #include "private.h" + #include "sk.h" +@@ -12,19 +13,44 @@ IMP_LUA_SK(X509_ALGOR, x509_algor) + + #define MYNAME "x509.algor" + +-void openssl_xalgor_free(X509_ALGOR* alg) ++/*** ++Create x509_algor object ++ ++@function new ++@treturn x509_algor mapping to X509_ALGOR in openssl ++*/ ++ ++static int openssl_xalgor_new(lua_State*L) + { +- X509_ALGOR_free(alg); +-} ++ X509_ALGOR* alg = X509_ALGOR_new(); ++ PUSH_OBJECT(alg, "openssl.x509_algor"); ++ return 1; ++}; + ++static luaL_Reg R[] = ++{ ++ {"new", openssl_xalgor_new}, + ++ {NULL, NULL}, ++}; ++ ++/*** ++openssl.x509_algor object ++@type x509_algor ++*/ + static int openssl_xalgor_gc(lua_State* L) + { + X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); +- openssl_xalgor_free(alg); ++ X509_ALGOR_free(alg); + return 0; + } + ++/*** ++clone the x509_algor ++ ++@function dup ++@treturn x509_algor clone of x509_algor ++*/ + static int openssl_xalgor_dup(lua_State* L) + { + X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); +@@ -34,6 +60,11 @@ static int openssl_xalgor_dup(lua_State* + } + + #if OPENSSL_VERSION_NUMBER >= 0x10002000L ++/*** ++compare with other x509_algor object ++@function equals ++@treturn boolean return true if two x509_algor equals ++*/ + static int openssl_xalgor_cmp(lua_State* L) + { + X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); +@@ -44,28 +75,38 @@ static int openssl_xalgor_cmp(lua_State* + #endif + + #if OPENSSL_VERSION_NUMBER >= 0x10001000L ++/*** ++set message digest object to x509_algor ++@function md ++@tparam number|string|evp_md md ++*/ + static int openssl_xalgor_md(lua_State* L) + { + X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); +- const EVP_MD* md = get_digest(L, 2); ++ const EVP_MD* md = get_digest(L, 2, NULL); + X509_ALGOR_set_md(alg, md); + return 0; + } + #endif + ++/*** ++get x509_algor properties ++@function get ++@tparam asn1_object ident algorithm, nil for fail ++@tparam asn1_string attached paramater value ++*/ + static int openssl_xalgor_get(lua_State* L) + { + int type; +- void* val; +- ASN1_OBJECT *obj, *dup; ++ CONSTIFY_X509_get0 void* val; ++ CONSTIFY_X509_get0 ASN1_OBJECT *obj; + +- X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); ++ CONSTIFY_X509_get0 X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); + + X509_ALGOR_get0(&obj, &type, &val, alg); + if (obj != NULL) + { +- dup = OBJ_dup(obj); +- PUSH_OBJECT(dup, "openssl.asn1_object"); ++ openssl_push_asn1object(L, obj); + } + else + lua_pushnil(L); +@@ -73,33 +114,50 @@ static int openssl_xalgor_get(lua_State* + lua_pushnil(L); + else + { +- ASN1_STRING *s = ASN1_STRING_dup(val); +- PUSH_OBJECT(s, "openssl.asn1_string"); ++ PUSH_ASN1_STRING(L, val); + } + + return 2; + } + ++/*** ++set x509_algor properties ++@function set ++@tparam asn1_object obj ident algorithm in openssl ++@tparam[opt] asn1_string val attached paramater value ++@treturn boolean result true for success, others for fail ++*/ ++/*** ++set digest algorithm, alias of set() ++only when OPENSSL_VERSION_NUMBER >= 0x10001000 ++@function set ++@tparam string|evp_digest digest algorithm ++*/ + static int openssl_xalgor_set(lua_State* L) + { + int ret = 0; + X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); + ASN1_OBJECT* obj = CHECK_OBJECT(2, ASN1_OBJECT, "openssl.asn1_object"); + ASN1_STRING* val = lua_isnoneornil(L, 3) ? +- NULL : auxiliar_checkgroup(L, "openssl.asn1_group", 3); ++ NULL : auxiliar_checkgroup(L, "openssl.asn1_string", 3); + obj = OBJ_dup(obj); + val = ASN1_STRING_dup(val); +- ret = X509_ALGOR_set0(alg, obj , val->type, val); ++ ret = X509_ALGOR_set0(alg, obj, val->type, val); + return openssl_pushresult(L, ret); + } + ++/*** ++convert x509_algor to txt string of asn1_object ++@function tostring ++@tparam string txt of asn1_object ++*/ + static int openssl_xalgor_tostring(lua_State* L) + { + int type; +- void* val; +- ASN1_OBJECT *obj; ++ CONSTIFY_X509_get0 void* val; ++ CONSTIFY_X509_get0 ASN1_OBJECT *obj; + +- X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); ++ CONSTIFY_X509_get0 X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); + + X509_ALGOR_get0(&obj, &type, &val, alg); + if (obj != NULL) +@@ -114,6 +172,15 @@ static int openssl_xalgor_tostring(lua_S + return 0; + } + ++/*** ++check with other x509_algor whether equals, alias with == operator ++only when OPENSSL_VERSION_NUMBER >= 0x10002000L ++ ++@function equals ++@tparam x509_algor other to compare ++*/ ++ ++ + static luaL_Reg xalgor_funcs[] = + { + {"dup", openssl_xalgor_dup}, +@@ -132,20 +199,6 @@ static luaL_Reg xalgor_funcs[] = + + {NULL, NULL}, + }; +- +-static int openssl_xalgor_new(lua_State*L) +-{ +- X509_ALGOR* alg = X509_ALGOR_new(); +- PUSH_OBJECT(alg, "openssl.x509_algor"); +- return 1; +-}; +- +-static luaL_Reg R[] = +-{ +- {"new", openssl_xalgor_new}, +- +- {NULL, NULL}, +-}; + + int openssl_register_xalgor(lua_State*L) + { +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/xattrs.c luvi-src-v2.7.6/deps/lua-openssl/src/xattrs.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/xattrs.c 2019-02-13 11:31:40.327301704 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/xattrs.c 2019-02-13 11:53:24.321792707 +0100 +@@ -1,49 +1,145 @@ +-/*=========================================================================*\ +-* xattrs.c +-* x509 attributes routines for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ +- ++/*** ++x509 attributes module for lua-openssl binding, Provide x509_attribute as lua object. ++Sometime when you make CSR,TS or X509, you maybe need to use this. ++ ++@module x509.attr ++@usage ++ attr = require('openssl').x509.attr ++*/ + #include "openssl.h" + #include "private.h" + #include "sk.h" + + #define MYNAME "x509.attribute" + ++/*** ++x509_attribute contrust param table. ++ ++@table x509_attribute_param_table ++@tfield string|integer|asn1_object object, identify a asn1_object ++@tfield string|integer type, same with type in asn1.new_string ++@tfield string|asn1_object value, value of attribute ++ ++@usage ++xattr = x509.attribute.new_attribute { ++ object = asn1_object, ++ type = Nid_or_String, ++ value = string or asn1_string value ++} ++*/ ++ ++/*** ++asn1_type object as table ++ ++@table asn1_type_table ++@tfield string value, value data ++@tfield string type, type of value ++@tfield string format, value is 'der', only exist when type is not in 'bit','bmp','octet' ++*/ ++ ++/*** ++Create x509_attribute object ++ ++@function new_attribute ++@tparam table attribute with object, type and value ++@treturn[1] x509_attribute mapping to X509_ATTRIBUTE in openssl ++ ++@see x509_attribute_param_table ++*/ ++static int openssl_xattr_new(lua_State*L) ++{ ++ X509_ATTRIBUTE *x = NULL; ++ luaL_checktable(L, 1); ++ ++ x = openssl_new_xattribute(L, &x, 1, NULL); ++ PUSH_OBJECT(x, "openssl.x509_attribute"); ++ return 1; ++} ++ ++static luaL_Reg R[] = ++{ ++ {"new_attribute", openssl_xattr_new}, ++ ++ {NULL, NULL}, ++}; ++ ++/*** ++x509_attribute infomation table ++ ++@table x509_attribute_info_table ++@tfield asn1_object|object object of asn1_object ++@tfield boolean single true for single value ++@tfield table value if single, value is asn1_type or array have asn1_type node table ++*/ + static int openssl_xattr_totable(lua_State*L, X509_ATTRIBUTE *attr) + { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + lua_newtable(L); + openssl_push_asn1object(L, attr->object); + lua_setfield(L, -2, "object"); + +- AUXILIAR_SET(L, -1, "single", attr->single, boolean); ++ lua_newtable(L); + if (attr->single) + { + openssl_push_asn1type(L, attr->value.single); +- lua_setfield(L, -2, "value"); ++ lua_rawseti(L, -2, 1); + } + else + { + int i; +- lua_newtable(L); + for (i = 0; i < sk_ASN1_TYPE_num(attr->value.set); i++) + { + ASN1_TYPE* t = sk_ASN1_TYPE_value(attr->value.set, i); + openssl_push_asn1type(L, t); + lua_rawseti(L, -2, i + 1); + } +- lua_setfield(L, -2, "value"); + } ++ lua_setfield(L, -2, "value"); + return 1; ++#else ++ int i, c; ++ ++ lua_newtable(L); ++ openssl_push_asn1object(L, X509_ATTRIBUTE_get0_object(attr)); ++ lua_setfield(L, -2, "object"); ++ ++ c = X509_ATTRIBUTE_count(attr); ++ lua_newtable(L); ++ for (i = 0; i < c; i++) ++ { ++ ASN1_TYPE* t = X509_ATTRIBUTE_get0_type(attr, i); ++ openssl_push_asn1type(L, t); ++ lua_rawseti(L, -2, i + 1); ++ } ++ lua_setfield(L, -2, "value"); ++ return 1; ++#endif + } + ++/*** ++openssl.x509_attribute object ++@type x509_attribute ++*/ ++ ++/*** ++get infomation table of x509_attribute. ++ ++@function info ++@treturn[1] table info, x509_attribute infomation as table ++@see x509_attribute_info_table ++*/ + static int openssl_xattr_info(lua_State*L) + { + X509_ATTRIBUTE* attr = CHECK_OBJECT(1, X509_ATTRIBUTE, "openssl.x509_attribute"); + return openssl_xattr_totable(L, attr); + } + ++/*** ++clone then asn1_attribute ++ ++@function dup ++@treturn x509_attribute attr clone of x509_attribute ++*/ + static int openssl_xattr_dup(lua_State*L) + { + X509_ATTRIBUTE* attr = CHECK_OBJECT(1, X509_ATTRIBUTE, "openssl.x509_attribute"); +@@ -59,6 +155,22 @@ static int openssl_xattr_free(lua_State* + return 0; + } + ++/*** ++get type of x509_attribute ++ ++@function data ++@tparam integer idx location want to get type ++@tparam string attrtype attribute type ++@treturn asn1_string ++*/ ++/*** ++set type of x509_attribute ++ ++@function data ++@tparam string attrtype attribute type ++@tparam string data set to asn1_attr ++@treturn boolean result true for success and others for fail ++*/ + static int openssl_xattr_data(lua_State*L) + { + X509_ATTRIBUTE* attr = CHECK_OBJECT(1, X509_ATTRIBUTE, "openssl.x509_attribute"); +@@ -68,12 +180,14 @@ static int openssl_xattr_data(lua_State* + size_t size; + int ret; + const char *data = luaL_checklstring(L, 3, &size); +- if (attr->single) ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ if (X509_ATTRIBUTE_count(attr) == 1) + ASN1_TYPE_free((ASN1_TYPE*)attr->value.ptr); + else + sk_ASN1_TYPE_pop_free(attr->value.set, ASN1_TYPE_free); + attr->value.ptr = NULL; +- ++#else ++#endif + ret = X509_ATTRIBUTE_set1_data(attr, attrtype, data, size); + return openssl_pushresult(L, ret); + } +@@ -82,12 +196,20 @@ static int openssl_xattr_data(lua_State* + int idx = luaL_checkint(L, 2); + int attrtype = luaL_checkint(L, 3); + ASN1_STRING *as = (ASN1_STRING *)X509_ATTRIBUTE_get0_data(attr, idx, attrtype, NULL); +- as = ASN1_STRING_dup(as); +- PUSH_OBJECT(as, "openssl.asn1_string"); ++ PUSH_ASN1_STRING(L, as); + return 1; + } + } + ++/*** ++get type of x509_attribute. ++ ++@function type ++@tparam[opt] integer location which location to get type, default is 0 ++@treturn table asn1_type, asn1_type as table info ++@treturn nil nil, fail return nothing ++@see asn1_type_table ++*/ + static int openssl_xattr_type(lua_State*L) + { + X509_ATTRIBUTE* attr = CHECK_OBJECT(1, X509_ATTRIBUTE, "openssl.x509_attribute"); +@@ -103,14 +225,27 @@ static int openssl_xattr_type(lua_State* + return 1; + } + ++/*** ++get asn1_object of x509_attribute. ++ ++@function object ++@treturn asn1_object object of x509_attribute ++*/ ++/*** ++set asn1_object for x509_attribute. ++ ++@function object ++@tparam asn1_object obj ++@treturn boolean true for success ++@return nil when occure error, and followed by error message ++*/ + static int openssl_xattr_object(lua_State*L) + { + X509_ATTRIBUTE* attr = CHECK_OBJECT(1, X509_ATTRIBUTE, "openssl.x509_attribute"); + if (lua_isnone(L, 2)) + { + ASN1_OBJECT* obj = X509_ATTRIBUTE_get0_object(attr); +- obj = OBJ_dup(obj); +- PUSH_OBJECT(obj, "openssl.asn1_object"); ++ openssl_push_asn1object(L, obj); + return 1; + } + else +@@ -146,6 +281,7 @@ X509_ATTRIBUTE* openssl_new_xattribute(l + size_t len = 0; + int nid; + const char* data = NULL; ++ ASN1_STRING *s = NULL; + + lua_getfield(L, idx, "object"); + nid = openssl_get_nid(L, -1); +@@ -178,18 +314,17 @@ X509_ATTRIBUTE* openssl_new_xattribute(l + { + data = lua_tolstring(L, -1, &len); + } +- else if (auxiliar_isgroup(L, "openssl.asn1group", -1)) ++ else if ((s = GET_GROUP(-1, ASN1_STRING, "openssl.asn1group")) != NULL) + { +- ASN1_STRING* value = CHECK_GROUP(-1, ASN1_STRING, "openssl.asn1group"); +- if (ASN1_STRING_type(value) != arttype) ++ if (ASN1_STRING_type(s) != arttype) + { + if (eprefix) + luaL_error(L, "%s field value not match type", eprefix); + else +- luaL_argcheck(L, ASN1_STRING_type(value) == arttype, idx, "field value not match type"); ++ luaL_argcheck(L, ASN1_STRING_type(s) == arttype, idx, "field value not match type"); + } +- data = (const char *)ASN1_STRING_data(value); +- len = ASN1_STRING_length(value); ++ data = (const char *)ASN1_STRING_data(s); ++ len = ASN1_STRING_length(s); + } + else + { +@@ -207,23 +342,6 @@ X509_ATTRIBUTE* openssl_new_xattribute(l + } + + +-static int openssl_xattr_new(lua_State*L) +-{ +- X509_ATTRIBUTE *x = NULL; +- luaL_checktable(L, 1); +- +- x = openssl_new_xattribute(L, &x, 1, NULL); +- PUSH_OBJECT(x, "openssl.x509_attribute"); +- return 1; +-} +- +-static luaL_Reg R[] = +-{ +- {"new_attribute", openssl_xattr_new}, +- +- {NULL, NULL}, +-}; +- + IMP_LUA_SK(X509_ATTRIBUTE, x509_attribute) + + int openssl_register_xattribute(lua_State*L) +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/xexts.c luvi-src-v2.7.6/deps/lua-openssl/src/xexts.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/xexts.c 2019-02-13 11:31:40.323968393 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/xexts.c 2019-02-13 11:53:24.321792707 +0100 +@@ -1,10 +1,11 @@ +-/*=========================================================================*\ +-* xexts.c +-* * x509 extension routines for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ +- ++/*** ++Provide x509_extension as lua object. ++Sometime when you make CSR,TS or X509, you maybe need to use this. ++ ++@module x509.extension ++@usage ++ extension = require('openssl').x509.extension ++*/ + #include + #include "openssl.h" + #include "private.h" +@@ -14,176 +15,21 @@ + + #define MYNAME "x509.extension" + +-static int openssl_xext_totable(lua_State* L, X509_EXTENSION *x) +-{ +- lua_newtable(L); +- openssl_push_asn1object(L, x->object); +- lua_setfield(L, -2, "object"); +- +- PUSH_ASN1_OCTET_STRING(L, x->value); +- lua_setfield(L, -2, "value"); +- +- AUXILIAR_SET(L, -1, "critical", x->critical, boolean); +- +- switch (x->object->nid) +- { +- case NID_subject_alt_name: +- { +- int i; +- int n_general_names; +- +- STACK_OF(GENERAL_NAME) *values = X509V3_EXT_d2i(x); +- +- if (values == NULL) +- break; +- +- /* Push ret[oid] */ +- openssl_push_asn1object(L, x->object); +- lua_newtable(L); +- n_general_names = sk_GENERAL_NAME_num(values); +- for (i = 0; i < n_general_names; i++) +- { +- GENERAL_NAME *general_name = sk_GENERAL_NAME_value(values, i); +- openssl_push_general_name(L, general_name); +- lua_rawseti(L, -2, i + 1); +- } +- lua_settable(L, -3); +- } +- default: +- break; +- } +- return 1; +-}; +- +-static int openssl_xext_info(lua_State* L) +-{ +- X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); +- return openssl_xext_totable(L, x); +-}; +- +-static int openssl_xext_dup(lua_State* L) +-{ +- X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); +- X509_EXTENSION *d = X509_EXTENSION_dup(x); +- PUSH_OBJECT(d, "openssl.x509_extension"); +- return 1; +-}; +- +-static int openssl_xext_export(lua_State* L) +-{ +- X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); +- unsigned char* p = NULL; +- int len = i2d_X509_EXTENSION(x, &p); +- if (len > 0) +- { +- lua_pushlstring(L, (const char *) p, len); +- OPENSSL_free(p); +- } +- else +- lua_pushnil(L); +- return 1; +-}; +- +-static int openssl_xext_free(lua_State* L) +-{ +- X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); +- X509_EXTENSION_free(x); +- return 0; +-}; +- +-static int openssl_xext_object(lua_State* L) +-{ +- X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); +- ASN1_OBJECT* obj; +- if (lua_isnone(L, 2)) +- { +- obj = X509_EXTENSION_get_object(x); +- obj = OBJ_dup(obj); +- PUSH_OBJECT(obj, "openssl.asn1_object"); +- return 1; +- } +- else +- { +- int nid = openssl_get_nid(L, 2); +- int ret; +- obj = OBJ_nid2obj(nid); +- ret = X509_EXTENSION_set_object(x, obj); +- return openssl_pushresult(L, ret); +- } +-}; +- +-static int openssl_xext_critical(lua_State* L) +-{ +- X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); +- if (lua_isnone(L, 2)) +- { +- lua_pushboolean(L, X509_EXTENSION_get_critical(x)); +- return 1; +- } +- else +- { +- int ret = X509_EXTENSION_set_critical(x, lua_toboolean(L, 2)); +- return openssl_pushresult(L, ret); +- } +-}; +- +-static int openssl_xext_data(lua_State* L) +-{ +- int ret = 0; +- X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); +- if (lua_isnone(L, 2)) +- { +- ASN1_STRING *s = X509_EXTENSION_get_data(x); +- s = ASN1_STRING_dup(s); +- PUSH_OBJECT(s, "openssl.asn1_string"); +- return 1; +- } +- else if (lua_isstring(L, 2)) +- { +- size_t size; +- const char* data = lua_tolstring(L, 2, &size); +- int type = lua_isnone(L, 3) ? V_ASN1_OCTET_STRING : luaL_checkint(L, 3); +- ASN1_STRING* s = ASN1_STRING_type_new(type); +- if (ASN1_STRING_set(s, data, size) == 1) +- { +- ret = X509_EXTENSION_set_data(x, s); +- } +- ASN1_STRING_free(s); +- return openssl_pushresult(L, ret); +- } +- else +- { +- ASN1_STRING* s = CHECK_GROUP(2, ASN1_STRING, "openssl.asn1group"); +- if (ASN1_STRING_type(s) == V_ASN1_OCTET_STRING) +- { +- ret = X509_EXTENSION_set_data(x, s); +- return openssl_pushresult(L, ret); +- } +- else +- { +- luaL_argerror(L, 2, "asn1_string type must be octet"); +- } +- } +- return 0; +-}; +- +-static luaL_Reg x509_extension_funs[] = +-{ +- {"info", openssl_xext_info}, +- {"dup", openssl_xext_dup}, +- {"export", openssl_xext_export}, +- +- /* set and get */ +- {"object", openssl_xext_object}, +- {"critical", openssl_xext_critical}, +- {"data", openssl_xext_data}, +- +- {"__gc", openssl_xext_free}, +- {"__tostring", auxiliar_tostring}, +- +- { NULL, NULL } +-}; ++/*** ++x509_extension contrust param table. + ++@table x509_extension_param_table ++@tfield boolean critical true set critical ++@tfield asn1_string value of x509_extension ++@tfield string|asn1_object object, object of extension ++ ++@usage ++xattr = x509.attrextension.new_extension { ++ object = asn1_object, ++ critical = false, ++ value = string or asn1_string value ++} ++*/ + static X509_EXTENSION* openssl_new_xextension(lua_State*L, int idx, int v3) + { + int nid; +@@ -205,13 +51,11 @@ static X509_EXTENSION* openssl_new_xexte + luaL_argerror(L, idx, lua_tostring(L, -1)); + } + lua_getfield(L, idx, "value"); +- +- luaL_argcheck(L, lua_isstring(L, -1) || auxiliar_isgroup(L, "openssl.asn1group", -1), +- 1, "field value must be string or openssl.asn1group object"); + if (lua_isstring(L, -1)) + { + size_t size; + const char* data = lua_tolstring(L, -1, &size); ++ lua_pop(L, 1); + if (v3) + { + const X509V3_EXT_METHOD *method = X509V3_EXT_get_nid(nid); +@@ -291,13 +135,25 @@ static X509_EXTENSION* openssl_new_xexte + } + else + { +- value = CHECK_GROUP(-1, ASN1_STRING, "openssl.asn1group"); +- y = X509_EXTENSION_create_by_NID(NULL, nid, critical, value); +- lua_pop(L, 1); +- return y; ++ value = GET_GROUP(-1, ASN1_STRING, "openssl.asn1group"); ++ if(value) ++ { ++ y = X509_EXTENSION_create_by_NID(NULL, nid, critical, value); ++ lua_pop(L, 1); ++ return y; ++ } + } ++ luaL_argerror(L, 1, "field value must be string or openssl.asn1group object"); ++ return NULL; + } + ++/*** ++Create x509_extension object ++@function new_extension ++@tparam table extension with object, value and critical ++@treturn x509_extension mapping to X509_EXTENSION in openssl ++@see x509_extension_param_table ++*/ + static int openssl_xext_new(lua_State* L) + { + X509_EXTENSION *x = NULL; +@@ -316,6 +172,12 @@ static int openssl_xext_new(lua_State* L + return 1; + }; + ++/*** ++read der encoded x509_extension ++@function read_extension ++@tparam string data der encoded ++@treturn x509_extension mappling to X509_EXTENSION in openssl ++*/ + static int openssl_xext_read(lua_State* L) + { + size_t size; +@@ -330,6 +192,23 @@ static int openssl_xext_read(lua_State* + return 1; + }; + ++/*** ++get all x509 certificate supported extensions ++@function support ++@treturn table contain all support extension info as table node {lname=..., sname=..., nid=...} ++*/ ++/*** ++check x509_extension object support or not ++@function support ++@tparam x509_extension extension ++@treturn boolean true for supported, false or not ++*/ ++/*** ++check nid or name support or not ++@function support ++@tparam number|string nid_or_name for extension ++@treturn boolean true for supported, false or not ++*/ + static int openssl_xext_support(lua_State*L) + { + static const int supported_nids[] = +@@ -369,7 +248,7 @@ static int openssl_xext_support(lua_Stat + }; + return 1; + } +- else if (auxiliar_isclass(L, "openssl.x509_extension", 1)) ++ else if (auxiliar_getclassudata(L, "openssl.x509_extension", 1)) + { + X509_EXTENSION* ext = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); + int ret = X509_supported_extension(ext); +@@ -402,6 +281,251 @@ static luaL_Reg R[] = + {NULL, NULL}, + }; + ++/*** ++openssl.x509_extension object ++@type x509_extension ++*/ ++ ++/*** ++x509_extension infomation table ++@todo double check ++@table x509_extension_info_table ++@tfield asn1_object|object object of x509_extension ++@tfield boolean|critical true for critical value ++@tfield string|value as octet string ++*/ ++static int openssl_xext_totable(lua_State* L, X509_EXTENSION *x) ++{ ++ ASN1_OBJECT *obj = X509_EXTENSION_get_object(x); ++ int nid = OBJ_obj2nid(obj); ++ lua_newtable(L); ++ openssl_push_asn1object(L, obj); ++ lua_setfield(L, -2, "object"); ++ ++ PUSH_ASN1_OCTET_STRING(L, X509_EXTENSION_get_data(x)); ++ lua_setfield(L, -2, "value"); ++ ++ AUXILIAR_SET(L, -1, "critical", X509_EXTENSION_get_critical(x), boolean); ++ ++ switch (nid) ++ { ++ case NID_subject_alt_name: ++ { ++ int i; ++ int n_general_names; ++ ++ STACK_OF(GENERAL_NAME) *values = X509V3_EXT_d2i(x); ++ ++ if (values == NULL) ++ break; ++ ++ /* Push ret[oid] */ ++ openssl_push_asn1object(L, obj); ++ lua_newtable(L); ++ n_general_names = sk_GENERAL_NAME_num(values); ++ for (i = 0; i < n_general_names; i++) ++ { ++ GENERAL_NAME *general_name = sk_GENERAL_NAME_value(values, i); ++ openssl_push_general_name(L, general_name); ++ lua_rawseti(L, -2, i + 1); ++ } ++ lua_settable(L, -3); ++ } ++ default: ++ break; ++ } ++ return 1; ++}; ++ ++/*** ++get infomation table of x509_extension. ++ ++@function info ++@tparam[opt] boolean|utf8 true for utf8 default ++@treturn[1] table info, x509_extension infomation as table ++@see x509_extension_info_table ++*/ ++static int openssl_xext_info(lua_State* L) ++{ ++ X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); ++ return openssl_xext_totable(L, x); ++}; ++ ++/*** ++clone then x509_extension ++ ++@function dup ++@treturn x509_extension clone of x509_extension ++*/ ++static int openssl_xext_dup(lua_State* L) ++{ ++ X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); ++ X509_EXTENSION *d = X509_EXTENSION_dup(x); ++ PUSH_OBJECT(d, "openssl.x509_extension"); ++ return 1; ++}; ++ ++/*** ++export x509_extenion to der encoded string ++@function export ++@treturn string ++*/ ++static int openssl_xext_export(lua_State* L) ++{ ++ X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); ++ unsigned char* p = NULL; ++ int len = i2d_X509_EXTENSION(x, &p); ++ if (len > 0) ++ { ++ lua_pushlstring(L, (const char *) p, len); ++ OPENSSL_free(p); ++ } ++ else ++ lua_pushnil(L); ++ return 1; ++}; ++ ++static int openssl_xext_free(lua_State* L) ++{ ++ X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); ++ X509_EXTENSION_free(x); ++ return 0; ++}; ++ ++/*** ++get asn1_object of x509_extension. ++@function object ++@treturn asn1_object object of x509_extension ++*/ ++ ++/*** ++set asn1_object for x509_extension. ++ ++@function object ++@tparam asn1_object obj ++@treturn boolean true for success ++@return nil when occure error, and followed by error message ++*/ ++static int openssl_xext_object(lua_State* L) ++{ ++ X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); ++ ASN1_OBJECT* obj; ++ if (lua_isnone(L, 2)) ++ { ++ obj = X509_EXTENSION_get_object(x); ++ openssl_push_asn1object(L, obj); ++ return 1; ++ } ++ else ++ { ++ int nid = openssl_get_nid(L, 2); ++ int ret; ++ obj = OBJ_nid2obj(nid); ++ ret = X509_EXTENSION_set_object(x, obj); ++ return openssl_pushresult(L, ret); ++ } ++}; ++ ++/*** ++get critical of x509_extension. ++ ++@function critical ++@treturn boolean true if extension set critical or false ++*/ ++/*** ++set critical of x509_extension. ++ ++@function critical ++@tparam boolean critical set to self ++@treturn boolean set critical success return true ++@return nil fail return nil, and followed by error message ++*/ ++static int openssl_xext_critical(lua_State* L) ++{ ++ X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); ++ if (lua_isnone(L, 2)) ++ { ++ lua_pushboolean(L, X509_EXTENSION_get_critical(x)); ++ return 1; ++ } ++ else ++ { ++ int ret = X509_EXTENSION_set_critical(x, lua_toboolean(L, 2)); ++ return openssl_pushresult(L, ret); ++ } ++}; ++ ++/*** ++get data of x509_extension ++ ++@function data ++@treturn asn1_string ++*/ ++ ++/*** ++set type of x509_extension ++ ++@function data ++@tparam asn1_string data set to self ++@treturn boolean result true for success ++@return nil for error, and followed by error message ++*/ ++static int openssl_xext_data(lua_State* L) ++{ ++ int ret = 0; ++ X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); ++ if (lua_isnone(L, 2)) ++ { ++ ASN1_STRING *s = X509_EXTENSION_get_data(x); ++ PUSH_ASN1_STRING(L, s); ++ return 1; ++ } ++ else if (lua_isstring(L, 2)) ++ { ++ size_t size; ++ const char* data = lua_tolstring(L, 2, &size); ++ int type = lua_isnone(L, 3) ? V_ASN1_OCTET_STRING : luaL_checkint(L, 3); ++ ASN1_STRING* s = ASN1_STRING_type_new(type); ++ if (ASN1_STRING_set(s, data, size) == 1) ++ { ++ ret = X509_EXTENSION_set_data(x, s); ++ } ++ ASN1_STRING_free(s); ++ return openssl_pushresult(L, ret); ++ } ++ else ++ { ++ ASN1_STRING* s = CHECK_GROUP(2, ASN1_STRING, "openssl.asn1group"); ++ if (ASN1_STRING_type(s) == V_ASN1_OCTET_STRING) ++ { ++ ret = X509_EXTENSION_set_data(x, s); ++ return openssl_pushresult(L, ret); ++ } ++ else ++ { ++ luaL_argerror(L, 2, "asn1_string type must be octet"); ++ } ++ } ++ return 0; ++}; ++ ++static luaL_Reg x509_extension_funs[] = ++{ ++ {"info", openssl_xext_info}, ++ {"dup", openssl_xext_dup}, ++ {"export", openssl_xext_export}, ++ ++ /* set and get */ ++ {"object", openssl_xext_object}, ++ {"critical", openssl_xext_critical}, ++ {"data", openssl_xext_data}, ++ ++ {"__gc", openssl_xext_free}, ++ {"__tostring", auxiliar_tostring}, ++ ++ { NULL, NULL } ++}; ++ + IMP_LUA_SK(X509_EXTENSION, x509_extension) + + int openssl_register_xextension(lua_State*L) +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/xname.c luvi-src-v2.7.6/deps/lua-openssl/src/xname.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/xname.c 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/xname.c 2019-02-13 11:53:24.321792707 +0100 +@@ -1,10 +1,11 @@ +-/*=========================================================================*\ +-* xname.c +-* * x509 name routines for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ +- ++/*** ++x509_name module for lua-openssl binding, provide x509_name as lua object ++Sometime when you make CSR,TS or X509, you maybe need to use this. ++ ++@module x509.name ++@usage ++ name = require('openssl').x509.name ++*/ + #include "openssl.h" + #include "private.h" + +@@ -12,6 +13,120 @@ + + #define MYNAME "x509.name" + ++int openssl_push_xname_asobject(lua_State*L, X509_NAME* xname) ++{ ++ X509_NAME* dup = X509_NAME_dup(xname); ++ PUSH_OBJECT(dup, "openssl.x509_name"); ++ return 1; ++} ++ ++static int openssl_new_xname(lua_State*L, X509_NAME* xname, int idx, int utf8) ++{ ++ int i, n; ++ luaL_checktable(L, idx); ++ luaL_argcheck(L, lua_istable(L, idx) && lua_rawlen(L, idx) > 0, idx, ++ "must be not empty table as array"); ++ ++ n = lua_rawlen(L, idx); ++ for (i = 0; i < n; i++) ++ { ++ lua_rawgeti(L, idx, i + 1); ++ lua_pushnil(L); ++ ++ while (lua_next(L, -2) != 0) ++ { ++ size_t size; ++ const char *value; ++ int ret; ++ int nid = openssl_get_nid(L, -2); ++ value = luaL_checklstring(L, -1, &size); ++ ++ if (nid == NID_undef) ++ { ++ lua_pushfstring(L, "node at %d which key (%s) is not a valid object identity", ++ i + 1, lua_tostring(L, -2)); ++ luaL_argerror(L, idx, lua_tostring(L, -1)); ++ } ++ ret = X509_NAME_add_entry_by_NID(xname, nid, utf8 ? MBSTRING_UTF8 : MBSTRING_ASC, (unsigned char*)value, (int)size, -1, 0); ++ if (ret != 1) ++ { ++ lua_pushfstring(L, "node at %d which %s=%s can't add to X509 name", ++ i + 1, lua_tostring(L, -2), value); ++ luaL_argerror(L, idx, lua_tostring(L, -1)); ++ } ++ lua_pop(L, 1); ++ } ++ } ++ return 0; ++} ++ ++/*** ++Create x509_name object ++ ++@function new ++@tparam table array include name node ++@tparam[opt] boolean utf8 encode will be use default ++@treturn x509_name mapping to X509_EXTENSION in openssl ++@usage ++ name = require'openssl'.x509.name ++ subject = name.new{ ++ {C='CN'}, ++ {O='kkhub.com'}, ++ {CN='zhaozg'} ++ } ++*/ ++static int openssl_xname_new(lua_State*L) ++{ ++ X509_NAME* xn; ++ int utf8; ++ luaL_checktable(L, 1); ++ utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); ++ xn = X509_NAME_new(); ++ openssl_new_xname(L, xn, 1, utf8); ++ PUSH_OBJECT(xn, "openssl.x509_name"); ++ return 1; ++}; ++ ++/*** ++Create x509_name from der string ++ ++@function d2i ++@tparam string content DER encoded string ++@treturn x509_name mapping to X509_NAME in openssl ++*/ ++static int openssl_xname_d2i(lua_State*L) ++{ ++ size_t len; ++ const unsigned char* dat = (const unsigned char*)luaL_checklstring(L, 1, &len); ++ X509_NAME* xn = d2i_X509_NAME(NULL, &dat, len); ++ if (xn) ++ PUSH_OBJECT(xn, "openssl.x509_name"); ++ else ++ openssl_pushresult(L, 0); ++ return 1; ++}; ++ ++static luaL_Reg R[] = ++{ ++ {"new", openssl_xname_new}, ++ {"d2i", openssl_xname_d2i}, ++ ++ {NULL, NULL}, ++}; ++ ++/*** ++x509_name infomation table ++other field is number type, and value table is alter name.(I not understand clearly) ++@table x509_extension_info_table ++@tfield asn1_object|object object of x509_name ++@tfield boolean|critical true for critical value ++@tfield string|value as octet string ++*/ ++ ++/*** ++openssl.x509_name object ++@type x509_name ++*/ + static int openssl_xname_gc(lua_State* L) + { + X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -19,6 +134,12 @@ static int openssl_xname_gc(lua_State* L + return 0; + } + ++/*** ++get oneline of x509_name. ++ ++@function oneline ++@treturn string line, name as oneline text ++*/ + static int openssl_xname_oneline(lua_State*L) + { + X509_NAME* xname = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -29,6 +150,12 @@ static int openssl_xname_oneline(lua_Sta + return 1; + }; + ++/*** ++get hash code of x509_name ++ ++@function hash ++@treturn integer hash hash code of x509_name ++*/ + static int openssl_xname_hash(lua_State*L) + { + X509_NAME* xname = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -37,10 +164,17 @@ static int openssl_xname_hash(lua_State* + return 1; + }; + ++/*** ++get digest of x509_name ++ ++@function digest ++@tparam string|nid|openssl.evp_md md method of digest ++@treturn string digest digest value by given alg of x509_name ++*/ + static int openssl_xname_digest(lua_State*L) + { + X509_NAME* xname = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +- const EVP_MD* md = get_digest(L, 2); ++ const EVP_MD* md = get_digest(L, 2, NULL); + unsigned char buf [EVP_MAX_MD_SIZE]; + unsigned int len = sizeof(buf); + +@@ -52,6 +186,15 @@ static int openssl_xname_digest(lua_Stat + return 1; + }; + ++/*** ++print x509_name to bio object ++ ++@function print ++@tparam openssl.bio out output bio object ++@tparam[opt] integer indent for output ++@tparam[opt] integer flags for output ++@treturn boolean result, follow by error message ++*/ + static int openssl_xname_print(lua_State*L) + { + X509_NAME* xname = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -68,42 +211,73 @@ static int openssl_xname_print(lua_State + return 1; + }; + +-static int openssl_push_xname_entry(lua_State* L, X509_NAME_ENTRY* ne) ++static int openssl_push_xname_entry(lua_State* L, X509_NAME_ENTRY* ne, int obj) + { + ASN1_OBJECT* object = X509_NAME_ENTRY_get_object(ne); +- ASN1_STRING *s; ++ ASN1_STRING* value = X509_NAME_ENTRY_get_data(ne); + lua_newtable(L); +- openssl_push_asn1object(L, object); +- s = X509_NAME_ENTRY_get_data(ne); +- PUSH_ASN1_STRING(L, s); ++ if(obj) ++ { ++ openssl_push_asn1object(L, object); ++ PUSH_ASN1_STRING(L, value); ++ } ++ else ++ { ++ lua_pushstring(L, OBJ_nid2sn(OBJ_obj2nid(object))); ++ lua_pushlstring(L, (const char*)ASN1_STRING_data(value), ASN1_STRING_length(value)); ++ } + lua_settable(L, -3); + return 1; + } + ++/*** ++return x509_name as table ++ ++@function info ++@tparam[opt=false] boolean asobject table key will use asn1_object or short name of asn1_object ++@treturn table names ++@see new ++*/ + static int openssl_xname_info(lua_State*L) + { + X509_NAME* name = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +- int i; +- int n_entries = X509_NAME_entry_count(name); ++ int obj = lua_isnoneornil(L, 2) ? 0 : lua_toboolean(L, 2); ++ int i, n; + lua_newtable(L); +- for (i = 0; i < n_entries; i++) ++ for (i = 0, n = X509_NAME_entry_count(name); i < n; i++) + { + X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, i); +- openssl_push_xname_entry(L, entry); ++ openssl_push_xname_entry(L, entry, obj); + lua_rawseti(L, -2, i + 1); + } + return 1; + }; + ++/*** ++compare two x509_name ++ ++@function cmp ++@tparam x509_name another to compare with ++@treturn boolean result true for equal or false ++@usage ++ name1 = name.new({...}) ++ name2 = name1:dup() ++ assert(name1:cmp(name2)==(name1==name2)) ++*/ + static int openssl_xname_cmp(lua_State*L) + { + X509_NAME* a = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +- X509_NAME* b = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); ++ X509_NAME* b = CHECK_OBJECT(2, X509_NAME, "openssl.x509_name"); + int ret = X509_NAME_cmp(a, b); + lua_pushboolean(L, ret == 0); + return 1; + }; + ++/*** ++make a clone of x509_name ++@function dup ++@treturn x509_name clone ++*/ + static int openssl_xname_dup(lua_State*L) + { + X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -112,6 +286,12 @@ static int openssl_xname_dup(lua_State*L + return 1; + }; + ++/*** ++get DER encoded string of x509_name. ++ ++@function i2d ++@treturn string der ++*/ + static int openssl_xname_i2d(lua_State*L) + { + X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -120,13 +300,19 @@ static int openssl_xname_i2d(lua_State*L + if (len > 0) + { + lua_pushlstring(L, (const char *)out, len); +- CRYPTO_free(out); ++ OPENSSL_free(out); + return 1; + } + else + return openssl_pushresult(L, len); + }; + ++/*** ++get count in x509_name. ++ ++@function entry_count ++@treturn integer count of x509_name ++*/ + static int openssl_xname_entry_count(lua_State*L) + { + X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -135,6 +321,14 @@ static int openssl_xname_entry_count(lua + return 1; + }; + ++/*** ++get text by given asn1_object or nid ++ ++@function get_text ++@tparam string|integer|asn1_object identid for asn1_object ++@tparam[opt=-1] number lastpos retrieve the next index after lastpos ++@treturn string text and followed by lastpos ++*/ + static int openssl_xname_get_text(lua_State*L) + { + X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -156,18 +350,35 @@ static int openssl_xname_get_text(lua_St + return 2; + }; + ++/*** ++get x509 name entry by index ++@function get_entry ++@tparam integer index start from 0, and less than xn:entry_count() ++@tparam[opt=false] boolean asobject table key will use asn1_object or short name of asn1_object ++@treturn x509 name entry table ++*/ + static int openssl_xname_get_entry(lua_State*L) + { + X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); + int lastpos = luaL_checkint(L, 2); ++ int obj = lua_isnoneornil(L, 3) ? 0 : lua_toboolean(L, 3); + X509_NAME_ENTRY *e = X509_NAME_get_entry(xn, lastpos); + if (e) + { +- return openssl_push_xname_entry(L, e); ++ return openssl_push_xname_entry(L, e, obj); + } + return 0; + }; + ++/*** ++add name entry ++ ++@function add_entry ++@tparam string|integer|asn1_object identid for asn1_object ++@tparam string data to add ++@tparam[opt] boolean utf8 true for use utf8 default ++@treturn boolean result true for success or follow by error message ++*/ + static int openssl_xname_add_entry(lua_State*L) + { + X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -189,6 +400,15 @@ static int openssl_xname_add_entry(lua_S + return openssl_pushresult(L, ret); + }; + ++/*** ++get index by give asn1_object or nid ++ ++@function delete_entry ++@tparam integer location which name entry to delete ++@treturn[1] asn1_object object that delete name entry ++@treturn[1] asn1_string value that delete name entry ++@treturn[2] nil delete nothing ++*/ + static int openssl_xname_delete_entry(lua_State*L) + { + X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); +@@ -197,10 +417,8 @@ static int openssl_xname_delete_entry(lu + X509_NAME_ENTRY *xe = X509_NAME_delete_entry(xn, loc); + if (xe) + { +- ASN1_OBJECT *obj = OBJ_dup(xe->object); +- ASN1_STRING *as = ASN1_STRING_dup(xe->value); +- PUSH_OBJECT(obj, "openssl.asn1_object"); +- PUSH_OBJECT(as, "openssl.asn1_string"); ++ openssl_push_asn1object(L, X509_NAME_ENTRY_get_object(xe)); ++ PUSH_ASN1_STRING(L, X509_NAME_ENTRY_get_data(xe)); + X509_NAME_ENTRY_free(xe); + return 2; + } +@@ -234,85 +452,6 @@ static luaL_Reg xname_funcs[] = + + {NULL, NULL}, + }; +- +-int openssl_push_xname_asobject(lua_State*L, X509_NAME* xname) +-{ +- X509_NAME* dup = X509_NAME_dup(xname); +- PUSH_OBJECT(dup, "openssl.x509_name"); +- return 1; +-} +- +-static int openssl_new_xname(lua_State*L, X509_NAME* xname, int idx, int utf8) +-{ +- int i, n; +- luaL_checktable(L, idx); +- luaL_argcheck(L, lua_istable(L, idx) && lua_rawlen(L, idx) > 0, idx, +- "must be not empty table as array"); +- +- n = lua_rawlen(L, idx); +- for (i = 0; i < n; i++) +- { +- lua_rawgeti(L, idx, i + 1); +- lua_pushnil(L); +- +- while (lua_next(L, -2) != 0) +- { +- size_t size; +- const char *value; +- int ret; +- int nid = openssl_get_nid(L, -2); +- value = luaL_checklstring(L, -1, &size); +- +- if (nid == NID_undef) +- { +- lua_pushfstring(L, "node at %d which key (%s) is not a valid object identity", +- i + 1, lua_tostring(L, -2)); +- luaL_argerror(L, idx, lua_tostring(L, -1)); +- } +- ret = X509_NAME_add_entry_by_NID(xname, nid, utf8 ? MBSTRING_UTF8 : MBSTRING_ASC, (unsigned char*)value, (int)size, -1, 0); +- if (ret != 1) +- { +- lua_pushfstring(L, "node at %d which %s=%s can't add to X509 name", +- i + 1, lua_tostring(L, -2), value); +- luaL_argerror(L, idx, lua_tostring(L, -1)); +- } +- lua_pop(L, 1); +- } +- } +- return 0; +-} +- +-static int openssl_xname_new(lua_State*L) +-{ +- X509_NAME* xn; +- int utf8; +- luaL_checktable(L, 1); +- utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); +- xn = X509_NAME_new(); +- openssl_new_xname(L, xn, 1, utf8); +- PUSH_OBJECT(xn, "openssl.x509_name"); +- return 1; +-}; +- +-static int openssl_xname_d2i(lua_State*L) +-{ +- size_t len; +- const unsigned char* dat = (const unsigned char*)luaL_checklstring(L, 1, &len); +- X509_NAME* xn = d2i_X509_NAME(NULL, &dat, len); +- if (xn) +- PUSH_OBJECT(xn, "openssl.x509_name"); +- else +- openssl_pushresult(L, 0); +- return 1; +-}; +- +-static luaL_Reg R[] = +-{ +- {"new", openssl_xname_new}, +- {"d2i", openssl_xname_d2i}, +- +- {NULL, NULL}, +-}; + + IMP_LUA_SK(X509_NAME, x509_name) + +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/src/xstore.c luvi-src-v2.7.6/deps/lua-openssl/src/xstore.c +--- luvi-src-v2.7.6.orig/deps/lua-openssl/src/xstore.c 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/src/xstore.c 2019-02-13 11:53:24.321792707 +0100 +@@ -1,18 +1,71 @@ +-/*=========================================================================*\ +-* xstore.c +-* * x509_store routines for lua-openssl binding +-* +-* Author: george zhao +-\*=========================================================================*/ +- ++/*** ++Provide x509_store as lua object, create and manage x509 store object ++@module x509.store ++@usage ++ store = require'openssl'.x509.store ++*/ + #include "openssl.h" + #include "private.h" + + #define MYNAME "x509.store" + ++/*** ++create or generate a new x509_store object. ++@function new ++@tparam table certs array of x509 objects, all x509 object will add to store, certs can be empty but not nil ++@tparam[opt] table crls array of x509_crl objects, all crl object will add to store ++@treturn x509_store object ++@see x509_store ++*/ ++static int openssl_xstore_new(lua_State*L) ++{ ++ X509_STORE* ctx = X509_STORE_new(); ++ int i, n; ++ luaL_checktable(L, 1); ++ n = lua_rawlen(L, 1); ++ for (i = 0; i < n; i++) ++ { ++ X509* x; ++ lua_rawgeti(L, 1, i + 1); ++ luaL_argcheck(L, auxiliar_getclassudata(L, "openssl.x509", -1), 1, "only contains x509 object"); ++ x = CHECK_OBJECT(-1, X509, "openssl.x509"); ++ lua_pop(L, 1); ++ X509_STORE_add_cert(ctx, x); ++ } ++ if (!lua_isnoneornil(L, 2)) ++ { ++ luaL_checktable(L, 2); ++ ++ n = lua_rawlen(L, 2); ++ for (i = 0; i < n; i++) ++ { ++ X509_CRL* c; ++ lua_rawgeti(L, 2, i + 1); ++ c = CHECK_OBJECT(-1, X509_CRL, "openssl.x509_crl"); ++ lua_pop(L, 1); ++ X509_STORE_add_crl(ctx, c); ++ } ++ }; ++ ++ PUSH_OBJECT(ctx, "openssl.x509_store"); ++ return 1; ++}; ++ ++static luaL_Reg R[] = ++{ ++ {"new", openssl_xstore_new}, ++ ++ {NULL, NULL}, ++}; ++ ++/*** ++openssl.x509_store object ++@type x509_store ++*/ + void openssl_xstore_free(X509_STORE* ctx) + { +-#if OPENSSL_VERSION_NUMBER < 0x10002000L ++ /* hack openssl bugs */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + if (ctx->references > 1) + CRYPTO_add(&ctx->references, -1, CRYPTO_LOCK_X509_STORE); + else +@@ -29,6 +82,14 @@ static int openssl_xstore_gc(lua_State* + return 0; + } + ++/*** ++add lookup path for store ++@function add_lookup ++@tparam string path file or dir path to add ++@tparam[opt='file'] mode only 'file' or 'dir' ++@tparam[opt='default'] format only 'pem', 'der' or 'default' ++@treturn boolean result ++*/ + static int openssl_xstore_add_lookup(lua_State* L) + { + X509_STORE* ctx = CHECK_OBJECT(1, X509_STORE, "openssl.x509_store"); +@@ -60,7 +121,12 @@ static int openssl_xstore_add_lookup(lua + return openssl_pushresult(L, ret); + } + +- ++/*** ++set verify depth of certificate chains ++@function depth ++@tparam number depth ++@treturn boolean result ++*/ + static int openssl_xstore_depth(lua_State* L) + { + X509_STORE* ctx = CHECK_OBJECT(1, X509_STORE, "openssl.x509_store"); +@@ -69,6 +135,12 @@ static int openssl_xstore_depth(lua_Stat + return openssl_pushresult(L, ret); + } + ++/*** ++set verify flags of certificate chains ++@function flags ++@tparam number flags ++@treturn boolean result ++*/ + static int openssl_xstore_flags(lua_State* L) + { + X509_STORE* ctx = CHECK_OBJECT(1, X509_STORE, "openssl.x509_store"); +@@ -77,6 +149,12 @@ static int openssl_xstore_flags(lua_Stat + return openssl_pushresult(L, ret); + } + ++/*** ++set prupose of x509 store ++@function purpose ++@tparam integer purpose ++@treturn boolean result ++*/ + static int openssl_xstore_purpose(lua_State* L) + { + X509_STORE* ctx = CHECK_OBJECT(1, X509_STORE, "openssl.x509_store"); +@@ -85,6 +163,12 @@ static int openssl_xstore_purpose(lua_St + return openssl_pushresult(L, ret); + } + ++/*** ++set as trust x509 store ++@function trust ++@tparam boolean trust ++@treturn boolean result ++*/ + static int openssl_xstore_trust(lua_State* L) + { + X509_STORE* ctx = CHECK_OBJECT(1, X509_STORE, "openssl.x509_store"); +@@ -93,6 +177,13 @@ static int openssl_xstore_trust(lua_Stat + return openssl_pushresult(L, ret); + } + ++/*** ++load certificate from file or dir,not given any paramater will load from defaults path ++@function load ++@tparam[opt] string filepath ++@tparam[opt] string dirpath ++@treturn boolean result ++*/ + static int openssl_xstore_load(lua_State* L) + { + X509_STORE* ctx = CHECK_OBJECT(1, X509_STORE, "openssl.x509_store"); +@@ -109,6 +200,12 @@ static int openssl_xstore_load(lua_State + return openssl_pushresult(L, ret); + } + ++/*** ++add x509 certificate or crl to store ++@param ... support x509 object,x509_crl object or array contains x509,x509_crl object ++@function add ++@treturn boolean result ++*/ + static int openssl_xstore_add(lua_State* L) + { + X509_STORE* ctx = CHECK_OBJECT(1, X509_STORE, "openssl.x509_store"); +@@ -124,12 +221,12 @@ static int openssl_xstore_add(lua_State* + for (j = 1; j <= k; j++) + { + lua_rawgeti(L, i, j); +- if (auxiliar_isclass(L, "openssl.x509", i)) ++ if (auxiliar_getclassudata(L, "openssl.x509", i)) + { + X509* x = CHECK_OBJECT(i, X509, "openssl.x509"); + ret = X509_STORE_add_cert(ctx, x); + } +- else if (auxiliar_isclass(L, "openssl.x509_crl", i)) ++ else if (auxiliar_getclassudata(L, "openssl.x509_crl", i)) + { + X509_CRL* c = CHECK_OBJECT(i, X509_CRL, "openssl.x509_crl"); + ret = X509_STORE_add_crl(ctx, c); +@@ -140,12 +237,12 @@ static int openssl_xstore_add(lua_State* + } + } + } +- else if (auxiliar_isclass(L, "openssl.x509", i)) ++ else if (auxiliar_getclassudata(L, "openssl.x509", i)) + { + X509* x = CHECK_OBJECT(i, X509, "openssl.x509"); + ret = X509_STORE_add_cert(ctx, x); + } +- else if (auxiliar_isclass(L, "openssl.x509_crl", i)) ++ else if (auxiliar_getclassudata(L, "openssl.x509_crl", i)) + { + X509_CRL* c = CHECK_OBJECT(i, X509_CRL, "openssl.x509_crl"); + ret = X509_STORE_add_crl(ctx, c); +@@ -186,47 +283,6 @@ static luaL_Reg xname_funcs[] = + + {NULL, NULL}, + }; +- +-static int openssl_xstore_new(lua_State*L) +-{ +- X509_STORE* ctx = X509_STORE_new(); +- int i, n; +- luaL_checktable(L, 1); +- n = lua_rawlen(L, 1); +- for (i = 0; i < n; i++) +- { +- X509* x; +- lua_rawgeti(L, 1, i + 1); +- luaL_argcheck(L, auxiliar_isclass(L, "openssl.x509", -1), 1, "only contains x509 object"); +- x = CHECK_OBJECT(-1, X509, "openssl.x509"); +- lua_pop(L, 1); +- X509_STORE_add_cert(ctx, x); +- } +- if (!lua_isnoneornil(L, 2)) +- { +- luaL_checktable(L, 2); +- +- n = lua_rawlen(L, 2); +- for (i = 0; i < n; i++) +- { +- X509_CRL* c; +- lua_rawgeti(L, 2, i + 1); +- c = CHECK_OBJECT(-1, X509_CRL, "openssl.x509_crl"); +- lua_pop(L, 1); +- X509_STORE_add_crl(ctx, c); +- } +- }; +- +- PUSH_OBJECT(ctx, "openssl.x509_store"); +- return 1; +-}; +- +-static luaL_Reg R[] = +-{ +- {"new", openssl_xstore_new}, +- +- {NULL, NULL}, +-}; + + int openssl_register_xstore(lua_State*L) + { +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/0.engine.lua luvi-src-v2.7.6/deps/lua-openssl/test/0.engine.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/0.engine.lua 2019-02-13 11:31:40.293968598 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/0.engine.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -5,7 +5,13 @@ TestEngine = {} + local eng = assert(openssl.engine('openssl')) + assert(eng:id(),'openssl') + assert(eng:set_default('RSA')) +- assert(eng:set_default('ECDSA')) ++ local _,sslv ++ _, _, sslv = openssl.version(true) ++ if sslv>=0x10100000 then ++ assert(eng:set_default('EC')) ++ else ++ assert(eng:set_default('ECDSA')) ++ end + end + + function TestEngine:testLoop() +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/1.asn1.lua luvi-src-v2.7.6/deps/lua-openssl/test/1.asn1.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/1.asn1.lua 2019-02-13 11:31:40.293968598 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/1.asn1.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -1,6 +1,5 @@ + local openssl = require'openssl' + local asn1 = openssl.asn1 +- + local first = true + + TestObject = {} +@@ -27,15 +26,19 @@ TestObject = {} + o3 = asn1.new_object(self.nid) + o4 = asn1.new_object(self.oid) + o5 = asn1.new_object(self.oid,true) +- +- o6 = asn1.new_object(self.ln,true) +- assertEquals(openssl.error(),218513530) +- ++ assert(o1) + assert(o1==o2) + assert(o1==o3) + assert(o1==o4) + assert(o1==o5) ++ ++ assertEquals(openssl.error(),nil) ++ ++ o6 = asn1.new_object(self.ln,true) + assertNil(o6) ++ assertNotNil(openssl.error()) ++ assertNil(openssl.error()) ++ + o6 = o1:dup() + assert(o1==o6) + +@@ -64,9 +67,10 @@ TestObject = {} + ln ='CCSTC GMSM2 EC1' + } + ++ assertNil(openssl.error()) + o7 = asn1.new_object(options.sn) + if not o7 then +- assertEquals(openssl.error(),218513530) ++ assertNotNil(openssl.error()) + o7 = asn1.new_object(options) + assertStrContains(tostring(o7), 'openssl.asn1_object') + assertEquals(o7:txt(), options.ln) +@@ -81,13 +85,16 @@ TestObject = {} + first = false + + assertIsNil(asn1.new_object(self.ne_sn)) ++ assertNotNil(openssl.error()) + assertIsNil(asn1.new_object(self.ne_ln)) ++ assertNotNil(openssl.error()) + assert(asn1.new_object(self.ne_oid)) + + o1 = assert(asn1.new_object({oid=self.ne_oid,sn=self.ne_sn,ln=self.ne_ln})) + o2 = assert(asn1.new_object(self.ne_oid)) + assertEquals(o1,o2) + ++ assertNil(openssl.error()) + else + assert(asn1.txt2nid(self.ne_oid)) + +@@ -151,4 +158,4 @@ TestTime = {} + assert(at:set(self.time)) + local t1 = at:get(self.time) + assertEquals(self.time,t1) +- end +\ No newline at end of file ++ end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/1.x509_attr.lua luvi-src-v2.7.6/deps/lua-openssl/test/1.x509_attr.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/1.x509_attr.lua 2019-02-13 11:31:40.287301977 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/1.x509_attr.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -36,10 +36,9 @@ TestX509attr = {} + local n1 = attr.new_attribute(self.ca) + assertStrContains(tostring(n1),'openssl.x509_attribute') + local info = n1:info() +- + assertIsTable(info) + assertEquals(info.object:ln(), "X509v3 Basic Constraints") +- assertEquals(info.single,false) ++ assertEquals(#info.value, 1) + assertEquals(info.value[1].type, asn1.OCTET_STRING) + assertEquals(info.value[1].value, "CA:FALSE") + local n2 = n1:dup() +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/1.x509_extension.lua luvi-src-v2.7.6/deps/lua-openssl/test/1.x509_extension.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/1.x509_extension.lua 2019-02-13 11:31:40.290635288 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/1.x509_extension.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -35,8 +35,9 @@ TestX509ext = {} + local info = n1:info() + assertIsTable(info) + assertEquals(info.object:ln(), "X509v3 Basic Constraints") +- assertEquals(info.critical,true) ++ assertEquals(info.critical,false) + assertEquals(info.value:tostring(), "CA:FALSE") ++ + local n2 = n1:dup() + assertEquals(n2:info(),info) + assertEquals(n1:critical(),false) +@@ -54,6 +55,7 @@ TestX509ext = {} + assertEquals(n1:data(), self.cafalse) + + local time = ext.new_extension(self.time) ++ assertEquals(time:critical(),true) + local der = time:export() + local t1 = ext.read_extension(der) + assert(der==t1:export()) +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/3.cipher.lua luvi-src-v2.7.6/deps/lua-openssl/test/3.cipher.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/3.cipher.lua 2019-02-13 11:31:40.283968667 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/3.cipher.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -91,7 +91,7 @@ TestCipherMY = {} + b = assert(obj1:update(a)) + b = b..assert(obj1:final()) + assertEquals(b,self.msg) +- assert(#a>#self.msg) ++ assert(#a >= #self.msg) + + obj = C:encrypt_new(self.key) + aa = assert(obj:update(self.msg)) +@@ -101,7 +101,7 @@ TestCipherMY = {} + bb = assert(obj1:update(aa)) + bb = bb..assert(obj1:final()) + assertEquals(self.msg,bb) +- assert(#self.msg < #aa) ++ assert(#self.msg <= #aa) + + local r = openssl.random(16) + local k,i = C:BytesToKey(r) +@@ -113,3 +113,33 @@ TestCipherMY = {} + assertEquals(#k,t.key_length) + assertEquals(#i,t.iv_length) + end ++ ++ function TestCipherMY:testAesCTR() ++ ++ local C = cipher.get('aes-128-ctr') ++ local key = '0123456789abcefg' ++ local iv = string.rep('\0',16) ++ ++ local a,b,c,aa,bb,cc ++ local obj,obj1 ++ ++ obj = C:new(true,self.key) ++ a = assert(obj:update(self.msg)) ++ a = a..obj:final() ++ ++ obj1 = C:new(false,self.key) ++ b = assert(obj1:update(a)) ++ b = b..assert(obj1:final()) ++ assertEquals(b,self.msg) ++ assert(#a>=#self.msg) ++ ++ obj = C:encrypt_new(self.key) ++ aa = assert(obj:update(self.msg)) ++ aa = aa..assert(obj:final()) ++ ++ obj1 = C:decrypt_new(self.key) ++ bb = assert(obj1:update(aa)) ++ bb = bb..assert(obj1:final()) ++ assertEquals(self.msg,bb) ++ assert(#self.msg <= #aa) ++ end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/4.pkey.lua luvi-src-v2.7.6/deps/lua-openssl/test/4.pkey.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/4.pkey.lua 2019-02-13 11:31:40.297301909 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/4.pkey.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -20,7 +20,7 @@ TestPKEYMY = {} + {'ec','prime256v1'} + } + end +- ++--[[ + function TestPKEYMY:testModule() + for i,v in ipairs(self.genalg ) do + --print(v) +@@ -30,7 +30,6 @@ TestPKEYMY = {} + + local t= k:parse() + local len = t.bits/8 +- --print_r(t) + + local msg = openssl.random(len-11) + if t.type=='rsa' then +@@ -54,17 +53,16 @@ TestPKEYMY = {} + + assert(k1:export():find('^-----BEGIN PUBLIC KEY-----')) + +- assert(string.len(k:export(true,true))>0) +- +- assert(string.len(k:export(true,true))>0) +- assert(string.len(k:export(true,false))>0) +- assert(string.len(k:export(false))>0) ++ assert(string.len(k:export('pem',true))>0) + +- assert(string.len(k:export(true,true,'secret'))>0) ++ assert(string.len(k:export('pem',true))>0) ++ assert(string.len(k:export('pem',false))>0) ++ assert(string.len(k:export('der'))>0) + +- assert(string.len(k:export(true,false,'secret'))>0) +- assert(string.len(k:export(false,'secret'))>0) ++ assert(string.len(k:export('pem',true,'secret'))>0) + ++ assert(string.len(k:export('pem',false,'secret'))>0) ++ assert(string.len(k:export('der',false,'secret'))>0) + end + end + +@@ -84,17 +82,16 @@ TestPKEYMY = {} + assert(t.e) + t.alg = 'rsa' + local r2 = pkey.new(t) +- assert(r2:is_private()==false) ++ assert(not r2:is_private()) + local msg = openssl.random(128-11) + + local out = pkey.encrypt(r2,msg) + local raw = pkey.decrypt(rsa,out) + assert(msg==raw) + end +- +- function testRsaFmt() ++--]] ++ function testKeyFmt() + local keys = { +- + RSA= {[[ + -----BEGIN PRIVATE KEY----- + MIICdQIBADALBgkqhkiG9w0BAQEEggJhMIICXQIBAAKBgQC7JHoJfg6yNzLMOWet +@@ -114,6 +111,7 @@ mu/UpE/BRZmR + -----END PRIVATE KEY----- + ]], + "3082025D02010002818100BB247A097E0EB23732CC3967ADF19E3D6B8283D1D0ACA4C018BE8D9800C07BFF0744C9CA1CBA36E12769FFB1E38D8BEE57A93AAA16433954197CAE692414F664FFBC74C6676C4CF1024969C72BE1E1A1A34314F4778FC8D0855A3595AC62A9C1210077A08B9730B45A2CB8902F48A005284BF20F8DEC8B4D034275D6AD81C011020301000102818000FCB94A260789512B537291E0183EA65E31EF9C0C162442D02833F9FAD03C540406C015F51B9AB32431AB3C6B4743B0D2A9DC05E18159B604E96661AAD70B008F3DE5BFA2F85E256C1E220FB4FD41E203315FDA20C5C0F3550EE1C9ECD73E2A0C01CA7B22CBACF42B27F0785FB5C2F9E8145A6E7E86BD6A9B200CBACC972011024100C9599F298A5B9FE32AD87EC2409FA845E53E118D3CED6EABCED06546D8C70763B52334F49F7E1CC7C7F965D1F4044238BE3A0C9D0825FCA371D9AE0C3961F489024100EDEFABA9D5399CEE591BFFCF48441BB632E74624F3047FDE95086D759E6717BA5CA4D4E2E24D77CEEB6629C596E062BBE5ACDC44625486ED640CCED060039D49024054D9187227E4BE76BB1A6A282F955812C42CA8B6CCE2FD0D1764C818D7C6DF3D4C1A9EF92AB0B92E12FDECC351C1EDA9FDB7769341D8C822941A77F69CC3C3890241008EF9A708ADB52A04DB8D04A1B5062034D2CFC089B17231B8398BCFE28EA5DA4F451E534266C4304B298EC16917298C8AE60F8268A141B3B6709975A92718E4E902410089EA6E6D70DF255F183F48DA63108BFEA80C940FDE9756538994E21E2C743C9181340BA640F8CB2A608CE002B78993CF189F4954FD7D3F9AEFD4A44FC1459991", ++"30819F300D06092A864886F70D010101050003818D0030818902818100BB247A097E0EB23732CC3967ADF19E3D6B8283D1D0ACA4C018BE8D9800C07BFF0744C9CA1CBA36E12769FFB1E38D8BEE57A93AAA16433954197CAE692414F664FFBC74C6676C4CF1024969C72BE1E1A1A34314F4778FC8D0855A3595AC62A9C1210077A08B9730B45A2CB8902F48A005284BF20F8DEC8B4D034275D6AD81C0110203010001", + "30818902818100BB247A097E0EB23732CC3967ADF19E3D6B8283D1D0ACA4C018BE8D9800C07BFF0744C9CA1CBA36E12769FFB1E38D8BEE57A93AAA16433954197CAE692414F664FFBC74C6676C4CF1024969C72BE1E1A1A34314F4778FC8D0855A3595AC62A9C1210077A08B9730B45A2CB8902F48A005284BF20F8DEC8B4D034275D6AD81C0110203010001" + }, + +@@ -126,7 +124,8 @@ zo0MUVPQgwJ3aJtNM1QMOQUayCrRwfklg+D/rFSU + -----END PRIVATE KEY----- + ]], + '30770201010420622AD3652C7EE4EF18EAD9467246BA5BA6ED262A1C76B76895F72E912A13124FA00A06082A8648CE3D030107A1440342000424BCF36EECF6B519CB16538BFBA6D35FA82255ABC0B1CE8D0C5153D0830277689B4D33540C39051AC82AD1C1F92583E0FFAC5494C0452AB5987B7C90E216ACF7', +-'0424BCF36EECF6B519CB16538BFBA6D35FA82255ABC0B1CE8D0C5153D0830277689B4D33540C39051AC82AD1C1F92583E0FFAC5494C0452AB5987B7C90E216ACF7' ++"3059301306072A8648CE3D020106082A8648CE3D0301070342000424BCF36EECF6B519CB16538BFBA6D35FA82255ABC0B1CE8D0C5153D0830277689B4D33540C39051AC82AD1C1F92583E0FFAC5494C0452AB5987B7C90E216ACF7", ++'3059301306072A8648CE3D020106082A8648CE3D0301070342000424BCF36EECF6B519CB16538BFBA6D35FA82255ABC0B1CE8D0C5153D0830277689B4D33540C39051AC82AD1C1F92583E0FFAC5494C0452AB5987B7C90E216ACF7' + }, + --]=] + DSA={ +@@ -142,103 +141,154 @@ vgPnEUG6Mk9bkxMZKRgsiKn6QGKDYGbOvnS1xmkM + -----END PRIVATE KEY----- + ]], + '308201BC02010002818100AA0930CC145825221CAFFA28AC2894196A27833DE5EC212707916894207774A2E7B238B0D36F1B2499A2C2585083EB01432924418D867FAA212DD1071D4DCEB2782794AD393CC08A4D4ADA7F68D6E839A5FCD34B4E402D82CB8A8CB40FEC31911BF9BD360B034CAACB4C5E947992573C9E90099C1B0F05940CABE5D2DE49A167021500ADC0E869B36F0AC013A681FDF4D4899D69820451028181008C6B4589AFA53A4D1048BFC346D1F386CA75521CCF72DDAA251286880EE13201FF48890BBFC33D79BACAEC71E7A778507BD5F1A66422E39415BE03E71141BA324F5B93131929182C88A9FA4062836066CEBE74B5C6690C7D101106C240AB7EBD54E4E3301FD086CE6ADAC922FB2713A2B0887CBA13B9BC68CE5CFFF241CD32460281802B260EA97DC6A12AE932C640E7DF3D8FF04A8A05A0324F8D5F1B23F15FA170FF3F42061124EFF2586CB11B49A82DCDC1B90FC6A84FB10109CB67DB5D2DA971AEAF17BE5E37284563E4C64D9E5FC8480258B319F0DE29D54D835070D9E287914D77DF81491F4423B62DA984EB3F45EB2A29FCEA5DAE525AC6AB6BCCE04BFDF5B6021500A535A8E1D0D91BEAFC8BEE1D9B2A3A8DE3311203', +-'0281802B260EA97DC6A12AE932C640E7DF3D8FF04A8A05A0324F8D5F1B23F15FA170FF3F42061124EFF2586CB11B49A82DCDC1B90FC6A84FB10109CB67DB5D2DA971AEAF17BE5E37284563E4C64D9E5FC8480258B319F0DE29D54D835070D9E287914D77DF81491F4423B62DA984EB3F45EB2A29FCEA5DAE525AC6AB6BCCE04BFDF5B6' ++"308201B73082012C06072A8648CE3804013082011F02818100AA0930CC145825221CAFFA28AC2894196A27833DE5EC212707916894207774A2E7B238B0D36F1B2499A2C2585083EB01432924418D867FAA212DD1071D4DCEB2782794AD393CC08A4D4ADA7F68D6E839A5FCD34B4E402D82CB8A8CB40FEC31911BF9BD360B034CAACB4C5E947992573C9E90099C1B0F05940CABE5D2DE49A167021500ADC0E869B36F0AC013A681FDF4D4899D69820451028181008C6B4589AFA53A4D1048BFC346D1F386CA75521CCF72DDAA251286880EE13201FF48890BBFC33D79BACAEC71E7A778507BD5F1A66422E39415BE03E71141BA324F5B93131929182C88A9FA4062836066CEBE74B5C6690C7D101106C240AB7EBD54E4E3301FD086CE6ADAC922FB2713A2B0887CBA13B9BC68CE5CFFF241CD3246038184000281802B260EA97DC6A12AE932C640E7DF3D8FF04A8A05A0324F8D5F1B23F15FA170FF3F42061124EFF2586CB11B49A82DCDC1B90FC6A84FB10109CB67DB5D2DA971AEAF17BE5E37284563E4C64D9E5FC8480258B319F0DE29D54D835070D9E287914D77DF81491F4423B62DA984EB3F45EB2A29FCEA5DAE525AC6AB6BCCE04BFDF5B6", ++"308201B73082012C06072A8648CE3804013082011F02818100AA0930CC145825221CAFFA28AC2894196A27833DE5EC212707916894207774A2E7B238B0D36F1B2499A2C2585083EB01432924418D867FAA212DD1071D4DCEB2782794AD393CC08A4D4ADA7F68D6E839A5FCD34B4E402D82CB8A8CB40FEC31911BF9BD360B034CAACB4C5E947992573C9E90099C1B0F05940CABE5D2DE49A167021500ADC0E869B36F0AC013A681FDF4D4899D69820451028181008C6B4589AFA53A4D1048BFC346D1F386CA75521CCF72DDAA251286880EE13201FF48890BBFC33D79BACAEC71E7A778507BD5F1A66422E39415BE03E71141BA324F5B93131929182C88A9FA4062836066CEBE74B5C6690C7D101106C240AB7EBD54E4E3301FD086CE6ADAC922FB2713A2B0887CBA13B9BC68CE5CFFF241CD3246038184000281802B260EA97DC6A12AE932C640E7DF3D8FF04A8A05A0324F8D5F1B23F15FA170FF3F42061124EFF2586CB11B49A82DCDC1B90FC6A84FB10109CB67DB5D2DA971AEAF17BE5E37284563E4C64D9E5FC8480258B319F0DE29D54D835070D9E287914D77DF81491F4423B62DA984EB3F45EB2A29FCEA5DAE525AC6AB6BCCE04BFDF5B6", + } + } + + for k,v in pairs(keys) do +- print(string.format('Test %s export format',k)) +- + local pri = pkey.read(v[1], true, 'pem') + local pub = assert(pri:get_public()) +- -- evp_pkey:export ([pem=true[, raw_key=false[, passphrase]]]) + +- --begin test pem format +- -- pem=true, raw_key=false, passphrase=nil ++ -- evp_pkey:export ([format='pem'[, raw=false[, passphrase]]]) ++ ++ -- private ++ --1 format='pem', raw=false, passphrase=nil + local pem1 = pri:export() + assertStrContains(pem1,'-----BEGIN PRIVATE KEY-----') + assertStrContains(pem1,'-----END PRIVATE KEY-----') + +- local pem1 = pri:export(true) ++ local pem1 = pri:export('pem') + assertStrContains(pem1,'-----BEGIN PRIVATE KEY-----') + assertStrContains(pem1,'-----END PRIVATE KEY-----') + +- local pem1 = pri:export(true, false) ++ local pem1 = pri:export('pem', false) + assertStrContains(pem1,'-----BEGIN PRIVATE KEY-----') + assertStrContains(pem1,'-----END PRIVATE KEY-----') + +- local k1 = pkey.read(pem1,true) ++ local k1 = pkey.read(pem1, true) + assertEquals(pri:export(),k1:export()) + +- -- pem=true, raw_key=false, export_private=false, passphrase=nil +- local pem1 = pub:export(true) +- assertStrContains(pem1,'-----BEGIN PUBLIC KEY-----') +- assertStrContains(pem1,'-----END PUBLIC KEY-----') +- +- local k2 = pkey.read(pem1,false) +- assertEquals(pub:export(),k2:export()) +- +- -- pem=true, raw_key=false, export_private=true, passphrase='secret' +- local pem3 = pri:export(true, false,'secret') ++ -- format='pem', raw=false, passphrase='secret' ++ local pem3 = pri:export('pem', false,'secret') + assertStrContains(pem3,'-----BEGIN ENCRYPTED PRIVATE KEY-----') + assertStrContains(pem3,'-----END ENCRYPTED PRIVATE KEY-----') + +- --ispriv = true, + local k2 = pkey.read(pem3, true, 'pem','secret') + assertEquals(pri:export(),k2:export()) + +- -- pem=true, raw_key=true, passphrase=nil +- local pem2 = pri:export(true, true) ++ --2 format='pem', raw=true, passphrase=nil ++ local pem2 = pri:export('pem', true) + assertStrContains(pem2,'-----BEGIN '..k..' PRIVATE KEY-----') + assertStrContains(pem2,'-----END '..k..' PRIVATE KEY-----') + assertNotStrContains(pem2,'Proc-Type: 4,ENCRYPTED') + assertNotStrContains(pem2,'DEK-Info: DES-EDE3-CBC,') + +- local k2 = pkey.read(pem2,true,'pem') ++ local k2 = pkey.read(pem2, true, 'pem') + assertEquals(pri:export(),k2:export()) + +- -- pem=true, raw_key=true, passphrase=nil +- if k~='EC' and k~='DSA' then +- local pem2 = pub:export(true, true) +- assertStrContains(pem2,'-----BEGIN '..k..' PUBLIC KEY-----') +- assertStrContains(pem2,'-----END '..k..' PUBLIC KEY-----') +- local k2 = pkey.read(pem2, false,'pem',k) +- --pem=true,raw_key=true +- assertEquals(pem2,k2:export(true,true)) +- end +- -- pem=true, raw_key=true, export_private=true, passphrase='secret' +- local pem4 = pri:export(true, true, 'secret') ++ -- format='pem' raw=true, passphrase='secret' ++ local pem4 = pri:export('pem', true, 'secret') + assertStrContains(pem4,'-----BEGIN '..k..' PRIVATE KEY-----') + assertStrContains(pem4,'Proc-Type: 4,ENCRYPTED') + assertStrContains(pem4,'DEK-Info: DES-EDE3-CBC,') + assertStrContains(pem4,'-----END '..k..' PRIVATE KEY-----') ++ + local k2 = pkey.read(pem4,true,'pem','secret') + assertEquals(pri:export(),k2:export()) +- --end of pem test + +- --test der +- -- pem=false, export_private=true, passphrase=nil +- local export = pri:export(false) ++ --3 format='der', raw=false, passphrase=nil ++ local export = pri:export('der') ++ local hex = openssl.hex(export) ++ assertEquals(hex:upper(),v[2]) ++ ++ local k2 = pkey.read(export,true,'der') ++ assertEquals(pri:export(),k2:export()) ++ ++ local export = pri:export('der',false) + local hex = openssl.hex(export) + assertEquals(hex:upper(),v[2]) + + local k2 = pkey.read(export,true,'der') + assertEquals(pri:export(),k2:export()) + +- -- pem=false, export_private=false, passphrase=nil +- local export = pub:export(false) ++ local export = pri:export('der', nil) ++ local hex = openssl.hex(export) ++ assertEquals(hex:upper(),v[2]) ++ ++ local k2 = pkey.read(export,true,'der') ++ assertEquals(pri:export(),k2:export()) ++ ++ -- pem=false, raw=false, passphrase='secret' ++ local export = pri:export('der',false,'secret') ++ local k2 = pkey.read(export,true,'der','secret') ++ assertEquals(pri:export(),k2:export()) ++ ++ local export = pri:export('der', nil, 'secret') ++ local k2 = pkey.read(export,true,'der','secret') ++ assertEquals(pri:export(),k2:export()) ++ ++ --4 pem=false, raw=true, passphrase=nil ++ local export = pri:export('der', true) ++ local hex = openssl.hex(export) ++ assertEquals(hex:upper(),v[2]) ++ ++ local k2 = pkey.read(export,true,'der', k) ++ assertEquals(pri:export(),k2:export()) ++ ++ ------------------------------- ++ -- public ++ --1 format='pem', raw=false, passphrase=nil ++ local pem1 = pub:export() ++ assertEquals(pem1, pub:export('pem')) ++ assertStrContains(pem1,'-----BEGIN PUBLIC KEY-----') ++ assertStrContains(pem1,'-----END PUBLIC KEY-----') ++ ++ local k2 = pkey.read(pem1,false) ++ assertEquals(pub:export(),k2:export()) ++ ++ --2 format='pem', raw=true, passphrase=nil ++ local pem2 = pub:export('pem', true) ++ if k~="EC" and k~='DSA' then ++ assertStrContains(pem2,'-----BEGIN '..k..' PUBLIC KEY-----') ++ assertStrContains(pem2,'-----END '..k..' PUBLIC KEY-----') ++ end ++ local k2 = pkey.read(pem2, false, 'pem', k) ++ assertEquals(pub:export(),k2:export()) ++ ++ --3 format='der', raw=false, passphrase=nil ++ local export = pub:export('der') + local hex = openssl.hex(export) + assertEquals(hex:upper(),v[3]) + +- if k~='EC' and k~='DSA' then +- local k1 = assert(pkey.read(export, false,'der',k)) +- local p1 = k1:export() +- assertEquals(p1,pub:export()) ++ local export = pub:export('der', false) ++ local k2 = pkey.read(export,false,'der') ++ assertEquals(hex:upper(),v[3]) ++ assertEquals(pub:export(),k2:export()) ++ ++ local k2 = pkey.read(export, nil,'der') ++ assertEquals(pub:export(),k2:export()) ++ ++ --4 format='der', raw=true, passphrase=nil ++ ++ local export = pub:export('der', true) ++ local hex = openssl.hex(export) ++ if (hex:upper()~=v[4]) then ++ print('XXXXXXXXX', k) ++ print('PUB:', hex) ++ print('---:', v[4]) ++ end ++ assertEquals(hex:upper(),v[4]) ++ ++ if (k~='EC' and k~='DSA') then ++ local k1 = assert(pkey.read(export, false,'der', k)) ++ local p1 = k1:export('der', true) ++ assertEquals(p1, export) ++ assertEquals(k1:export(), pub:export()) + end +- -- pkcs8 der +- -- pem=false, export_private=true, passphrase='secret' +- local export = pri:export(false,'secret') +- local k1 = pkey.read(export,true,'der','secret') +- assertEquals(pri:export(),k1:export()) + end + end ++ ++--"" #EXPORT_ASSERT_TO_GLOBALS = true ++--"" #require'luaunit' ++--"" # LuaUnit.run() +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/5.ts.lua luvi-src-v2.7.6/deps/lua-openssl/test/5.ts.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/5.ts.lua 2019-02-13 11:31:40.290635288 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/5.ts.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -2,58 +2,499 @@ local openssl = require'openssl' + + local asn1,ts,asn1,csr = openssl.asn1,openssl.ts,openssl.asn1, openssl.x509.req + +-local timeStamping = openssl.asn1.new_string('timeStamping',asn1.OCTET_STRING) +-local timeStamping=asn1.new_type('timeStamping') +-timeStamping = timeStamping:i2d() +-local cafalse = openssl.asn1.new_string('CA:FALSE',asn1.OCTET_STRING) ++ ++testTSRequest = {} ++ ++ function testTSRequest:setUp() ++ self.msg = 'abcd' ++ self.alg = 'sha1' ++ self.hash = assert(openssl.digest.digest(self.alg, self.msg, true)) ++ end ++ ++ function testTSRequest:testReq1() ++ local req = assert(openssl.ts.req_new()) ++ assert(req:msg_imprint(self.hash, self.alg)) ++ assert(req:cert_req(true)) ++ local der = assert(req:export()) ++ local req1 = assert(ts.req_read(der)) ++ local t = req1:info() ++ assertIsTable(t) ++ assertEquals(t.cert_req,true) ++ assertEquals(t.version,1) ++ assertEquals(t.msg_imprint.hashed_msg,self.hash) ++ assertEquals(t.msg_imprint.hash_algo:tostring(), self.alg) ++ return req ++ end ++ ++ function testTSRequest:testReq2() ++ local req = assert(openssl.ts.req_new()) ++ assert(req:msg_imprint(self.hash, self.alg)) ++ local nonce = openssl.bn.text(openssl.random(16)) ++ assert(req:nonce(nonce)) ++ ++ local der = assert(req:export()) ++ local req1 = assert(ts.req_read(der)) ++ local t = req1:info() ++ assertIsTable(t) ++ assertEquals(t.cert_req,false) ++ assertEquals(t.version,1) ++ ++ assertEquals(t.nonce:data(), nonce:totext()) ++ assertEquals(t.msg_imprint.hashed_msg,self.hash) ++ assertEquals(t.msg_imprint.hash_algo:tostring(), self.alg) ++ self.nonce = nonce ++ return req ++ end ++ ++ function testTSRequest:testReq3() ++ local req = assert(openssl.ts.req_new()) ++ assert(req:msg_imprint(self.hash, self.alg)) ++ local nonce = openssl.bn.text(openssl.random(16)) ++ assert(req:nonce(nonce)) ++ ++ local oid = '1.2.3.4.100' ++ ++ local obj = assert(asn1.new_object(oid)) ++ assert(req:policy_id(obj)) ++ ++ local der = assert(req:export()) ++ local req1 = assert(ts.req_read(der)) ++ local t = req1:info() ++ assertIsTable(t) ++ assertEquals(t.cert_req,false) ++ assertEquals(t.version,1) ++ ++ assertEquals(t.nonce:data(), nonce:totext()) ++ assertEquals(t.policy_id:data(), oid) ++ assertEquals(t.msg_imprint.hashed_msg,self.hash) ++ assertEquals(t.msg_imprint.hash_algo:tostring(), self.alg) ++ return req ++ end + + local first = true +-TestTS = {} +- function TestTS:setUp() +- self.alg='sha1' ++testTSSign = {} + +- self.cadn = {{commonName='CA'},{C='CN'}} +- self.tsadn = {{commonName='tsa'},{C='CN'}} ++ function testTSSign:setUp() ++ local timeStamping = openssl.asn1.new_string('timeStamping',asn1.OCTET_STRING) ++ local timeStamping=asn1.new_type('timeStamping') ++ self.timeStamping = timeStamping:i2d() ++ self.cafalse = openssl.asn1.new_string('CA:FALSE',asn1.OCTET_STRING) + ++ self.dat=[[ ++[test] ++basicConstraints=CA:FALSE ++keyUsage = nonRepudiation, digitalSignature, keyEncipherment ++extendedKeyUsage = critical,timeStamping ++]] ++ self.alg='sha1' + self.digest = 'sha1WithRSAEncryption' + self.md = openssl.digest.get('sha1WithRSAEncryption') ++ self.hash = assert(self.md:digest(self.dat)) ++ if first then ++ assert(asn1.new_object({oid='1.2.3.4.5.6',sn='1.2.3.4.5.6_sn',ln='1.2.3.4.5.6_ln'})) ++ assert(asn1.new_object({oid='1.2.3.4.5.7',sn='1.2.3.4.5.7_sn',ln='1.2.3.4.5.7_ln'})) ++ first = false ++ end ++ ++ --setUp private key and certificate ++ local ca = {} ++ self.ca = ca ++ ca.dn = {{commonName='CA'},{C='CN'}} ++ ca.pkey = assert(openssl.pkey.new()) ++ local subject = assert(openssl.x509.name.new(ca.dn)) ++ ca.req = assert(csr.new(subject,ca.pkey)) ++ ca.cert = assert(ca.req:to_x509(ca.pkey)) ++ ++ local attributes = ++ { ++ { ++ object='basicConstraints', ++ type=asn1.OCTET_STRING, ++ value=cafalse ++ } ++ } ++ local extensions = ++ { ++ openssl.x509.extension.new_extension( ++ { ++ object='extendedKeyUsage', ++ value = 'timeStamping', ++ critical = true ++ })} ++ ++ local tsa = {} ++ self.tsa = tsa ++ tsa.dn = {{commonName='tsa'},{C='CN'}} ++ tsa.pkey = assert(openssl.pkey.new()) ++ subject = openssl.x509.name.new(tsa.dn) ++ ++ tsa.req = csr.new(subject,tsa.pkey) ++ assertEquals(type(tsa.req:parse()),'table') ++ ++ tsa.cert = openssl.x509.new(1, tsa.req) ++ assert(tsa.cert:validat(os.time(), os.time() + 3600*24*365)) ++ assert(tsa.cert:extensions(extensions)) ++ assert(tsa.cert:sign(ca.pkey,ca.cert)) ++ ++ assertEquals(type(tsa.cert:parse()),'table') ++ ++ ca.store = openssl.x509.store.new({ca.cert}) ++ assert(tsa.cert:check(ca.store,nil,'timestamp_sign')) ++ ++ local args = {} ++ args.attribs = {} ++ args.extentions = {} ++ args.digest = 'sha1WithRSAEncryption' ++ args.num_days = 3650 ++ args.serialNumber = 1 ++ end ++ ++ ++ function testTSSign:testSign1() ++ testTSRequest:setUp() ++ local req = testTSRequest:testReq1() ++ ++ local tsa = self.tsa ++ local req_ctx = assert(ts.resp_ctx_new(tsa.cert, tsa.pkey)) ++ assert(req_ctx:md({'md5','sha1'})) ++ local res = req_ctx:sign(req) ++ t = assert(res:info()) ++ assertIsTable(t) ++ assert(t.status_info.status:tostring()=='02') ++ assertEquals(#t.status_info.text,1) ++ assertEquals(t.status_info.text[1],'Error during response generation.') ++ end ++ ++ function testTSSign:testSign2() ++ testTSRequest:setUp() ++ local req = testTSRequest:testReq2() ++ ++ local tsa = self.tsa ++ local oid = '1.2.3.4.5.7' ++ local req_ctx = assert(ts.resp_ctx_new(tsa.cert, tsa.pkey, oid)) ++ assert(req_ctx:md({'md5','sha1'})) ++ local res = req_ctx:sign(req) ++ t = assert(res:info()) ++ assertIsTable(t) ++ ++ assert(t.status_info.status:tostring()=='0') ++ assert(not t.status_info.text) ++ assert(not t.status_info.failure_info) ++ assertIsTable(t.tst_info) ++ assertIsUserdata(t.token) ++ ++ local tst = t.tst_info ++ assertEquals(tst.serial:tostring(),'01') ++ assertEquals(tst.version,1) ++ assertEquals(tst.ordering,false) ++ assertEquals(tst.policy_id:txt(true),oid) ++ ++ local now = os.time() ++ local function get_timezone() ++ local now = os.time() ++ return os.difftime(now, os.time(os.date("!*t", now))) ++ end ++ timezone = get_timezone() ++ ++ assertEquals(tst.time:tostring(),os.date('%Y%m%d%H%M%SZ',now-timezone)) ++ assertIsString(tst.nonce:tostring()) ++ ++ local res = assert(openssl.ts.resp_read(res:export())) ++ local vry = assert(req:to_verify_ctx()) ++ vry:store(self.ca.store) ++ assert(vry:verify(res)) ++ end ++ ++ function testTSSign:testSign3() ++ testTSRequest:setUp() ++ local req = testTSRequest:testReq3() ++ ++ local tsa = self.tsa ++ local oid = '1.2.3.4.100' ++ local obj = assert(asn1.new_object(oid)) ++ local req_ctx = assert(ts.resp_ctx_new(tsa.cert, tsa.pkey, obj)) ++ assert(req_ctx:md({'md5','sha1'})) ++ local res = req_ctx:sign(req) ++ t = assert(res:info()) ++ assertIsTable(t) ++ ++ assert(t.status_info.status:tostring()=='0') ++ assert(not t.status_info.text) ++ assert(not t.status_info.failure_info) ++ assertIsTable(t.tst_info) ++ assertIsUserdata(t.token) ++ ++ local tst = t.tst_info ++ assertEquals(tst.serial:tostring(),'01') ++ assertEquals(tst.version,1) ++ assertEquals(tst.ordering,false) ++ assertEquals(tst.policy_id:txt(true),oid) ++ ++ local now = os.time() ++ local function get_timezone() ++ local now = os.time() ++ return os.difftime(now, os.time(os.date("!*t", now))) ++ end ++ timezone = get_timezone() ++ ++ assertEquals(tst.time:tostring(),os.date('%Y%m%d%H%M%SZ',now-timezone)) ++ assertIsString(tst.nonce:tostring()) ++ ++ local res = assert(openssl.ts.resp_read(res:export())) ++ local vry = assert(req:to_verify_ctx()) ++ vry:store(self.ca.store) ++ assert(vry:verify(res)) ++ end ++ ++ function testTSSign:testSign4() ++ testTSRequest:setUp() ++ local req = testTSRequest:testReq3() ++ ++ local tsa = self.tsa ++ local oid = '1.2.3.4.100' ++ local obj = assert(asn1.new_object(oid)) ++ local req_ctx = assert(ts.resp_ctx_new(tsa.cert, tsa.pkey, obj)) ++ assert(req_ctx:md({'md5','sha1'})) ++ local res = req_ctx:sign(req) ++ t = assert(res:info()) ++ assertIsTable(t) ++ ++ assert(t.status_info.status:tostring()=='0') ++ assert(not t.status_info.text) ++ assert(not t.status_info.failure_info) ++ assertIsTable(t.tst_info) ++ assertIsUserdata(t.token) ++ ++ local tst = t.tst_info ++ assertEquals(tst.serial:tostring(),'01') ++ assertEquals(tst.version,1) ++ assertEquals(tst.ordering,false) ++ assertEquals(tst.policy_id:txt(true),oid) ++ ++ local now = os.time() ++ local function get_timezone() ++ local now = os.time() ++ return os.difftime(now, os.time(os.date("!*t", now))) ++ end ++ timezone = get_timezone() ++ ++ assertEquals(tst.time:tostring(),os.date('%Y%m%d%H%M%SZ',now-timezone)) ++ assertIsString(tst.nonce:tostring()) ++ ++ local res = assert(openssl.ts.resp_read(res:export())) ++ local vry = ts.verify_ctx_new(req) ++ vry:store(self.ca.store) ++ assert(vry:verify(res)) ++ end ++ ++ function testTSSign:testSign5() ++ testTSRequest:setUp() ++ local req = testTSRequest:testReq3() ++ ++ local tsa = self.tsa ++ local oid = '1.2.3.4.100' ++ local obj = assert(asn1.new_object(oid)) ++ local req_ctx = assert(ts.resp_ctx_new(tsa.cert, tsa.pkey, obj)) ++ assert(req_ctx:md({'md5','sha1'})) ++ local res = req_ctx:sign(req) ++ t = assert(res:info()) ++ assertIsTable(t) ++ ++ assert(t.status_info.status:tostring()=='0') ++ assert(not t.status_info.text) ++ assert(not t.status_info.failure_info) ++ assertIsTable(t.tst_info) ++ assertIsUserdata(t.token) ++ ++ local tst = t.tst_info ++ assertEquals(tst.serial:tostring(),'01') ++ assertEquals(tst.version,1) ++ assertEquals(tst.ordering,false) ++ assertEquals(tst.policy_id:txt(true),oid) ++ ++ local now = os.time() ++ local function get_timezone() ++ local now = os.time() ++ return os.difftime(now, os.time(os.date("!*t", now))) ++ end ++ timezone = get_timezone() ++ ++ assertEquals(tst.time:tostring(),os.date('%Y%m%d%H%M%SZ',now-timezone)) ++ assertIsString(tst.nonce:tostring()) ++ ++ local vry = assert(ts.verify_ctx_new()) ++ vry:imprint(self.hash) ++ vry:store(self.ca.store) ++ assert(vry:verify(res)) ++ end ++ ++ function testTSSign:testSign6() ++ testTSRequest:setUp() ++ local req = testTSRequest:testReq3() ++ ++ local tsa = self.tsa ++ local oid = '1.2.3.4.100' ++ local obj = assert(asn1.new_object(oid)) ++ local req_ctx = assert(ts.resp_ctx_new(tsa.cert, tsa.pkey, obj)) ++ assert(req_ctx:md({'md5','sha1'})) ++ local res = req_ctx:sign(req) ++ t = assert(res:info()) ++ assertIsTable(t) ++ ++ assert(t.status_info.status:tostring()=='0') ++ assert(not t.status_info.text) ++ assert(not t.status_info.failure_info) ++ assertIsTable(t.tst_info) ++ assertIsUserdata(t.token) ++ ++ local tst = t.tst_info ++ assertEquals(tst.serial:tostring(),'01') ++ assertEquals(tst.version,1) ++ assertEquals(tst.ordering,false) ++ assertEquals(tst.policy_id:txt(true),oid) ++ ++ local now = os.time() ++ local function get_timezone() ++ local now = os.time() ++ return os.difftime(now, os.time(os.date("!*t", now))) ++ end ++ timezone = get_timezone() ++ ++ assertEquals(tst.time:tostring(),os.date('%Y%m%d%H%M%SZ',now-timezone)) ++ assertIsString(tst.nonce:tostring()) ++ ++ local vry = assert(ts.verify_ctx_new()) ++ vry:data(self.dat) ++ vry:store(self.ca.store) ++ assert(vry:verify(res)) ++ end ++ ++ function testTSSign:testSign7() ++ testTSRequest:setUp() ++ local req = testTSRequest:testReq3() ++ ++ local tsa = self.tsa ++ local oid = '1.2.3.4.100' ++ local obj = assert(asn1.new_object(oid)) ++ local req_ctx = assert(ts.resp_ctx_new(tsa.cert, tsa.pkey, obj)) ++ assert(req_ctx:md({'md5','sha1'})) ++ local res = req_ctx:sign(req) ++ t = assert(res:info()) ++ assertIsTable(t) ++ ++ assert(t.status_info.status:tostring()=='0') ++ assert(not t.status_info.text) ++ assert(not t.status_info.failure_info) ++ assertIsTable(t.tst_info) ++ assertIsUserdata(t.token) ++ ++ local tst = t.tst_info ++ assertEquals(tst.serial:tostring(),'01') ++ assertEquals(tst.version,1) ++ assertEquals(tst.ordering,false) ++ assertEquals(tst.policy_id:txt(true),oid) ++ ++ local now = os.time() ++ local function get_timezone() ++ local now = os.time() ++ return os.difftime(now, os.time(os.date("!*t", now))) ++ end ++ timezone = get_timezone() ++ ++ assertEquals(tst.time:tostring(),os.date('%Y%m%d%H%M%SZ',now-timezone)) ++ assertIsString(tst.nonce:tostring()) ++ ++ local vry = assert(ts.verify_ctx_new()) ++ vry:imprint(self.hash) ++ vry:data(self.dat) ++ vry:store(self.ca.store) ++ assert(vry:verify(res)) ++ end ++ ++ function testTSSign:testSign8() ++ testTSRequest:setUp() ++ local req = testTSRequest:testReq3() ++ ++ local tsa = self.tsa ++ local oid = '1.2.3.4.100' ++ local obj = assert(asn1.new_object(oid)) ++ local req_ctx = assert(ts.resp_ctx_new(tsa.cert, tsa.pkey, obj)) ++ assert(req_ctx:md({'md5','sha1'})) ++ assert(req_ctx:policies({assert(asn1.new_object('1.1.3')),assert(asn1.new_object('1.1.4'))})) ++ local res = req_ctx:sign(req) ++ t = assert(res:info()) ++ assertIsTable(t) ++ ++ assert(t.status_info.status:tostring()=='0') ++ assert(not t.status_info.text) ++ assert(not t.status_info.failure_info) ++ assertIsTable(t.tst_info) ++ assertIsUserdata(t.token) ++ ++ local tst = t.tst_info ++ assertEquals(tst.serial:tostring(),'01') ++ assertEquals(tst.version,1) ++ assertEquals(tst.ordering,false) ++ assertEquals(tst.policy_id:txt(true),oid) ++ local now = os.time() ++ local function get_timezone() ++ local now = os.time() ++ return os.difftime(now, os.time(os.date("!*t", now))) ++ end ++ timezone = get_timezone() ++ ++ assertEquals(tst.time:tostring(),os.date('%Y%m%d%H%M%SZ',now-timezone)) ++ assertIsString(tst.nonce:tostring()) ++ ++ local vry = assert(ts.verify_ctx_new()) ++ vry:imprint(self.hash) ++ vry:data(self.dat) ++ vry:store(self.ca.store) ++ assert(vry:verify(res)) ++ end ++ ++testTSComplex = {} ++ ++ function testTSComplex:setUp() ++ local timeStamping = openssl.asn1.new_string('timeStamping',asn1.OCTET_STRING) ++ local timeStamping=asn1.new_type('timeStamping') ++ self.timeStamping = timeStamping:i2d() ++ self.cafalse = openssl.asn1.new_string('CA:FALSE',asn1.OCTET_STRING) ++ + self.dat=[[ + [test] + basicConstraints=CA:FALSE + keyUsage = nonRepudiation, digitalSignature, keyEncipherment + extendedKeyUsage = critical,timeStamping + ]] ++ self.alg='sha1' ++ self.digest = 'sha1WithRSAEncryption' ++ self.md = openssl.digest.get('sha1WithRSAEncryption') + self.hash = assert(self.md:digest(self.dat)) + if first then + assert(asn1.new_object({oid='1.2.3.4.5.6',sn='1.2.3.4.5.6_sn',ln='1.2.3.4.5.6_ln'})) + assert(asn1.new_object({oid='1.2.3.4.5.7',sn='1.2.3.4.5.7_sn',ln='1.2.3.4.5.7_ln'})) + first = false + end +- end + +-function TestTS:testAll() +- local args = {} +- args.attribs = {} +- args.extentions = {} +- args.digest = 'sha1WithRSAEncryption' +- args.num_days = 3650 +- args.serialNumber = 1 +- +- local cakey = assert(openssl.pkey.new()) +- local careq = assert(csr.new(openssl.x509.name.new(self.cadn),cakey)) +- local cacert = assert(careq:to_x509(cakey)) +- +- local pkey = assert(openssl.pkey.new()) +- local subject = openssl.x509.name.new(self.tsadn) +- local attributes = ++ --setUp private key and certificate ++ local ca = {} ++ self.ca = ca ++ ca.dn = {{commonName='CA'},{C='CN'}} ++ ca.pkey = assert(openssl.pkey.new()) ++ local subject = assert(openssl.x509.name.new(ca.dn)) ++ ca.req = assert(csr.new(subject,ca.pkey)) ++ ca.cert = assert(ca.req:to_x509(ca.pkey)) ++ ++ local attributes = ++ { + { +- { +- object='basicConstraints', +- type=asn1.OCTET_STRING, +- value=cafalse +- } ++ object='basicConstraints', ++ type=asn1.OCTET_STRING, ++ value=cafalse + } +- local extensions = ++ } ++ local extensions = + { + openssl.x509.extension.new_extension( + { +@@ -61,75 +502,86 @@ function TestTS:testAll() + value = 'timeStamping', + critical = true + })} +- x = csr.new( +- subject, +- pkey +- ) +- t = assert(x:parse()) +- assertEquals(type(t),'table') +- --print_r(t) +- +- local x509 = openssl.x509.new( +- 1, +- x +- ) +- assert(x509:validat(os.time(), os.time() + 3600*24*365)) +- assert(x509:extensions(extensions)) +- assert(x509:sign(cakey,cacert)) +- t = assert(x509:parse()) +- assertEquals(type(t),'table') +- --print_r(t) +- +- --------------------------------------------------- +- local req = assert(openssl.ts.req_new()) +- assert(req:msg_imprint(self.hash,'sha1')) +- assert(req:cert_req(true)) +- local der = assert(req:export()) +- local req1 = assert(ts.req_read(der)) +- local t = req1:info() +- assertIsTable(t) +- --print_r(t) +- +- local req_ctx = assert(ts.resp_ctx_new(x509, pkey, '1.2.3.4.5.7')) +- assert(req_ctx:md({'md5','sha1'})) +- --assert(req_ctx:policies({'1.1.3','1.1.4'})) +- local res = req_ctx:sign(req) +- +- t = assert(res:info()) +- assertIsTable(t) +- --print_r(t) +- t = res:tst_info() +- assertIsTable(t) +- --print_r(t) +- +- local skx = openssl.x509.store.new({cacert}) +- +- assert(x509:check(skx,nil,'timestamp_sign')) +- +- local res = assert(openssl.ts.resp_read(res:export())) +- local vry = assert(req:to_verify_ctx()) +- assert(vry:store(skx)) +- assert(vry:verify(res)) +- +- local vry = ts.verify_ctx_new(req) +- assert(vry:store(skx)) +- assert(vry:verify(res)) +- +- local vry = assert(ts.verify_ctx_new()) +- assert(vry:imprint(self.hash)) +- assert(vry:store(skx)) +- assert(vry:verify(res)) +- +- local vry = assert(ts.verify_ctx_new()) +- assert(vry:data(self.dat)) +- assert(vry:store(skx)) +- assert(vry:verify(res)) +- +- local vry = assert(ts.verify_ctx_new()) +- assert(vry:imprint(self.hash)) +- assert(vry:data(self.dat)) +- assert(vry:store(skx)) +- assert(vry:verify(res)) +- res = ts.resp_read(res:export()) +- vry:verify(res) +-end ++ ++ local tsa = {} ++ self.tsa = tsa ++ tsa.dn = {{commonName='tsa'},{C='CN'}} ++ tsa.pkey = assert(openssl.pkey.new()) ++ subject = openssl.x509.name.new(tsa.dn) ++ ++ tsa.req = csr.new(subject,tsa.pkey) ++ assertEquals(type(tsa.req:parse()),'table') ++ ++ tsa.cert = openssl.x509.new(1, tsa.req) ++ assert(tsa.cert:validat(os.time(), os.time() + 3600*24*365)) ++ assert(tsa.cert:extensions(extensions)) ++ assert(tsa.cert:sign(ca.pkey,ca.cert)) ++ ++ assertEquals(type(tsa.cert:parse()),'table') ++ ++ ca.store = openssl.x509.store.new({ca.cert}) ++ assert(tsa.cert:check(ca.store,nil,'timestamp_sign')) ++ ++ local args = {} ++ args.attribs = {} ++ args.extentions = {} ++ args.digest = 'sha1WithRSAEncryption' ++ args.num_days = 3650 ++ args.serialNumber = 1 ++ end ++ ++ function testTSComplex:testCallback() ++ testTSRequest:setUp() ++ local req = testTSRequest:testReq3() ++ ++ local tsa = self.tsa ++ local oid = '1.2.3.4.100' ++ local obj = assert(asn1.new_object(oid)) ++ local req_ctx = assert(ts.resp_ctx_new(tsa.cert, tsa.pkey, obj)) ++ assert(req_ctx:md({'md5','sha1'})) ++ assert(req_ctx:policies({assert(asn1.new_object('1.1.3')),assert(asn1.new_object('1.1.4'))})) ++ ++ local sn = 0 ++ req_ctx:set_serial_cb(function(self) ++ sn = sn + 1 ++ return sn ++ end) ++ ++ local now = os.time() ++ req_ctx:set_time_cb(function(self) ++ return now ++ end) ++ ++ assert(pcall(function() ++ local res = req_ctx:sign(req) ++ t = assert(res:info()) ++ assertIsTable(t) ++ ++ assert(t.status_info.status:tostring()=='0') ++ assert(not t.status_info.text) ++ assert(not t.status_info.failure_info) ++ assertIsTable(t.tst_info) ++ assertIsUserdata(t.token) ++ ++ local tst = t.tst_info ++ assertEquals(tst.serial:tostring(),string.format('%02x',sn)) ++ assertEquals(tst.version,1) ++ assertEquals(tst.ordering,false) ++ assertEquals(tst.policy_id:txt(true),oid) ++ ++ local function get_timezone() ++ local now = os.time() ++ return os.difftime(now, os.time(os.date("!*t", now))) ++ end ++ timezone = get_timezone() ++ ++ assertEquals(tst.time:tostring(),os.date('%Y%m%d%H%M%SZ',now-timezone)) ++ assertIsString(tst.nonce:tostring()) ++ local vry = assert(ts.verify_ctx_new()) ++ vry:imprint(self.hash) ++ vry:data(self.dat) ++ vry:store(self.ca.store) ++ assert(vry:verify(res)) ++ ++ end)) ++ end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/5.x509.lua luvi-src-v2.7.6/deps/lua-openssl/test/5.x509.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/5.x509.lua 2019-02-13 11:31:40.293968598 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/5.x509.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -2,6 +2,8 @@ local openssl = require'openssl' + + local csr,x509 = openssl.x509.req, openssl.x509 + ++local helper = require('helper') ++ + TestX509 = {} + function TestX509:setUp() + self.alg='sha1' +@@ -13,33 +15,24 @@ TestX509 = {} + end + + function TestX509:testNew() +- --cacert, self sign +- local pkey = assert(openssl.pkey.new()) +- local req = assert(csr.new(self.cadn,pkey)) +- local t = req:parse() +- assertEquals(type(t),'table') +- +- local cacert = openssl.x509.new( +- 1, --serialNumber +- req --copy name and extensions +- ) +- +- cacert:validat(os.time(), os.time() + 3600*24*365) +- assert(cacert:sign(pkey, cacert)) --self sign ++ local pkey, cacert = helper.new_ca(self.cadn) + assertEquals(cacert:subject(), cacert:issuer()) ++ assert(cacert:parse().ca, 'invalid ca certificate') + + local c = cacert:pubkey():encrypt('abcd') + d = pkey:decrypt(c) + assert(d=='abcd') + assert(cacert:check(pkey),'self sign check failed') +- assert(cacert:check(openssl.x509.store.new({cacert}) )) ++ local castore = openssl.x509.store.new({cacert}) ++ assert(cacert:check(castore)) + + --sign cert by cacert + + local dkey = openssl.pkey.new() + req = assert(csr.new(self.dn,dkey)) + local cert = openssl.x509.new(2,req) +- cert:validat(os.time(), os.time() + 3600*24*365) ++ cert:notbefore(os.time()) ++ cert:validat(os.time(), os.time() + 3600*24*360) + assert(cert:sign(pkey,cacert)) + + local c = cert:pubkey():encrypt('abcd') +@@ -47,7 +40,7 @@ function TestX509:testNew() + assert(d=='abcd') + assert(cert:check(dkey),'self private match failed') + +- assert(cert:check(openssl.x509.store.new({cacert}))) ++ assert(cert:check(castore)) + end + + function TestX509:testIO() +@@ -75,8 +68,6 @@ sggwDQYJKoZIhvcNAQEEBQADQQCU5SSgapJSdRXJ + assert(x:notbefore()) + assert(x:notafter()) + +- print(os.date('%c', x:notafter():get())) +- + assertIsNil(x:extensions()) + + assert(x:subject()) +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/5.x509_req.lua luvi-src-v2.7.6/deps/lua-openssl/test/5.x509_req.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/5.x509_req.lua 2019-02-13 11:31:40.290635288 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/5.x509_req.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -160,7 +160,7 @@ TestCSR = {} + assertEquals(req1:subject():tostring(),self.subject:tostring()) + + local s = req1:digest() +- local r = req1:digest('sha1') ++ local r = req1:digest('sha256') + assertEquals(r,s) + assert(req2:check(pkey)) + +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/6.cms.lua luvi-src-v2.7.6/deps/lua-openssl/test/6.cms.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/6.cms.lua 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/6.cms.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -0,0 +1,86 @@ ++local openssl = require'openssl' ++local bio, x509,cms,csr = openssl.bio,openssl.x509,openssl.cms,openssl.x509.req ++local helper = require'helper' ++if not cms then ++ print('Skip cms test') ++ return ++end ++ ++TestCMS = {} ++ ++--need OpenSSL build with zlib support ++--[[ ++ function TestCMS:testCompress() ++ local msg = openssl.random(1000) ++ local cs = assert(cms.compress(msg, 'rle')) ++ local out = bio.mem() ++ local ret = assert(cms.uncompress (cs, msg, out)) ++ assertEquals(msg, out:get_mem()) ++ end ++--]] ++ function TestCMS:setUp() ++ self.alg='sha1' ++ self.cadn = openssl.x509.name.new({{commonName='CA'},{C='CN'}}) ++ self.alicedn = openssl.x509.name.new({{commonName='Alice'},{C='CN'}}) ++ self.bobdn = openssl.x509.name.new({{commonName='Bob'},{C='CN'}}) ++ ++ local cakey, cacert = helper.new_ca(self.cadn) ++ self.cakey, self.cacert = cakey, cacert ++ self.castore = openssl.x509.store.new({cacert}) ++ ++ local pkey = openssl.pkey.new() ++ req = assert(csr.new(self.alicedn, pkey)) ++ local cert = openssl.x509.new(2,req) ++ cert:validat(os.time(), os.time() + 3600*24*365) ++ assert(cert:sign(cakey,cacert)) ++ self.alice = { ++ key = pkey, ++ cert = cert ++ } ++ ++ pkey = openssl.pkey.new() ++ req = assert(csr.new(self.bobdn, pkey)) ++ cert = openssl.x509.new(2,req) ++ cert:validat(os.time(), os.time() + 3600*24*365) ++ assert(cert:sign(cakey,cacert)) ++ self.bob = { ++ key = pkey, ++ cert = cert ++ } ++ ++ self.msg = openssl.hex(openssl.random(128)) ++ self.digest = 'sha1WithRSAEncryption' ++ end ++ ++ function TestCMS:testEncrypt() ++ local recipts = {self.alice.cert} ++ local msg = assert(cms.encrypt(recipts, self.msg)) ++ local smime = assert(cms.write(msg)) ++ local ss = assert(cms.read(smime,'smime')) ++ local raw = assert(cms.decrypt(ss,self.alice.key, self.alice.cert)) ++ assertEquals(raw,self.msg) ++ end ++ ++ function TestCMS:testSign() ++ local c1 = assert(cms.sign(self.bob.cert, self.bob.key, self.msg, {})) ++ local smime = assert(cms.write(c1)) ++ local msg = assert(cms.verify(c1, {self.bob.cert}, self.castore)) ++ assertEquals(msg, self.msg) ++ msg = assert(cms.verify(c1, {}, self.castore)) ++ assertEquals(msg, self.msg) ++ end ++ ++ function TestCMS:testEncryptedData() ++ local key = openssl.random(24) ++ local c1 = assert(cms.EncryptedData_encrypt(self.msg, key)) ++ local smime = assert(cms.write(c1)) ++ local msg = assert(cms.EncryptedData_decrypt(c1, key)) ++ assertEquals(msg, self.msg) ++ end ++ function TestCMS:testDigest() ++ local key = openssl.random(24) ++ local c1 = assert(cms.digest_create(self.msg)) ++ local smime = assert(cms.write(c1)) ++ local msg = assert(cms.digest_verify(c1)) ++ assertEquals(msg, self.msg) ++ end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/6.pkcs7.lua luvi-src-v2.7.6/deps/lua-openssl/test/6.pkcs7.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/6.pkcs7.lua 2019-02-13 11:31:40.293968598 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/6.pkcs7.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -1,5 +1,6 @@ + local openssl = require'openssl' + local x509,pkcs7,csr = openssl.x509,openssl.pkcs7,openssl.x509.req ++local helper = require'helper' + + TestCompat = {} + function TestCompat:setUp() +@@ -11,18 +12,7 @@ TestCompat = {} + end + + function TestCompat:testNew() +- local cakey = assert(openssl.pkey.new()) +- local req = assert(csr.new(self.cadn,cakey)) +- local t = req:parse() +- assertEquals(type(t),'table') +- +- local cacert = openssl.x509.new( +- 1, --serialNumber +- req --copy name and extensions +- ) +- cacert:validat(os.time(), os.time() + 3600*24*361) +- assert(cacert:sign(cakey, cacert)) --self sign +- ++ local cakey, cacert = helper.new_ca(self.cadn) + local dkey = openssl.pkey.new() + req = assert(csr.new(self.dn,dkey)) + +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/7.pkcs12.lua luvi-src-v2.7.6/deps/lua-openssl/test/7.pkcs12.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/7.pkcs12.lua 2019-02-13 11:31:40.293968598 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/7.pkcs12.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -1,5 +1,6 @@ + local openssl = require'openssl' + local csr, x509, pkcs12 = openssl.x509.req,openssl.x509, openssl.pkcs12 ++local helper = require'helper' + + TestCompat = {} + function TestCompat:setUp() +@@ -12,17 +13,9 @@ TestCompat = {} + + + function TestCompat:testNew() +- local pkey = assert(openssl.pkey.new()) +- local req = assert(csr.new(self.cadn,pkey)) +- local t = req:parse() +- assertEquals(type(t),'table') +- +- local cacert = openssl.x509.new( +- 1, --serialNumber +- req --copy name and extensions +- ) ++ local pkey, cacert = helper.new_ca(self.cadn) + local dkey = openssl.pkey.new() +- req = assert(csr.new(self.dn,dkey)) ++ local req = assert(csr.new(self.dn,dkey)) + + local extensions = + {{ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/8.ssl_options.lua luvi-src-v2.7.6/deps/lua-openssl/test/8.ssl_options.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/8.ssl_options.lua 2019-02-13 11:31:40.290635288 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/8.ssl_options.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -1,13 +1,15 @@ + -- Testcase +-local ssl = require "openssl".ssl ++local openssl = require'openssl' ++local ssl = openssl.ssl ++local helper = require'helper' + + local proto = 'TLSv1' +- + local SET = function(t) + local s = {} + for _, k in ipairs(t) do s[k] = true end + return s + end ++local libressl = helper.libressl + + TestSSLOptions = {} + function TestSSLOptions:setUp() +@@ -18,16 +20,18 @@ TestSSLOptions = {} + local t, e = self.ctx:options() + assert(type(t) == "table", e or type(t)) + t = SET(t) +- ++ assertIsTable(t) ++ assertEquals(0, #t) ++ + t = self.ctx:options(ssl.no_sslv3, "no_ticket") + t = SET(t) + assertIsTable(t) +- assert(t.no_sslv3) ++ assert(libressl or t.no_sslv3) + assert(t.no_ticket) + + assert(not pcall(self.ctx.options, ctx, true, nil)) + assertIsTable(t) +- assert(t.no_sslv3) ++ assert(libressl or t.no_sslv3) + assert(t.no_ticket) + end + +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/9.issue.lua luvi-src-v2.7.6/deps/lua-openssl/test/9.issue.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/9.issue.lua 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/9.issue.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -0,0 +1,76 @@ ++local openssl = require'openssl' ++local hmac = require'openssl'.hmac ++ ++TestIssuer = {} ++ function dump(t,i) ++ for k,v in pairs(t) do ++ if type(v) == 'table' then ++ print( string.rep('\t',i),k..'={') ++ dump(v,i+1) ++ print( string.rep('\t',i),'}') ++ elseif type(v) == 'userdata' then ++ local s = tostring(v) ++ if s:match('^openssl.asn1_') then ++ if type(k)=='userdata' and tostring(k):match('^openssl.asn1_object') then ++ print( string.rep('\t',i),k:sn()..'='..v:data() ) ++ elseif s:match('^openssl.asn1_integer') then ++ print( string.rep('\t',i),tostring(k)..'='..tostring(v),v:bn()) ++ else ++ print( string.rep('\t',i),tostring(k)..'='..tostring(v),v:data()) ++ end ++ elseif s:match('^openssl.x509_name') then ++ print( string.rep('\t',i),k..'='..v:oneline()) ++ print( string.rep('\t',i),k..'={') ++ dump(v:info(true), i+1) ++ print( string.rep('\t',i),k..'=}') ++ elseif s:match('^openssl.x509_extension') then ++ print( string.rep('\t',i),k..'={') ++ dump(v:info(true), i+1) ++ print(string.rep('\t',i),'}') ++ elseif s:match('^openssl.x509_algor') then ++ print(string.rep('\t',i), k..'='..v:tostring()) ++ else ++ print( string.rep('\t',i),k..'='..v) ++ end ++ else ++ print( string.rep('\t',i),k..'='..tostring(v)) ++ end ++ end ++ end ++ ++ function TestIssuer:test75() ++ local certasstring = [[ ++-----BEGIN CERTIFICATE----- ++MIIDATCCArCgAwIBAgITEgAFDVkfna1KLEIuKgAAAAUNWTAIBgYqhQMCAgMwfzEj ++MCEGCSqGSIb3DQEJARYUc3VwcG9ydEBjcnlwdG9wcm8ucnUxCzAJBgNVBAYTAlJV ++MQ8wDQYDVQQHEwZNb3Njb3cxFzAVBgNVBAoTDkNSWVBUTy1QUk8gTExDMSEwHwYD ++VQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDIwHhcNMTUwNjEzMTczNjQ4WhcN ++MTUwOTEzMTc0NjQ4WjATMREwDwYDVQQDEwhuZ2F0ZS5ydTBjMBwGBiqFAwICEzAS ++BgcqhQMCAiQABgcqhQMCAh4BA0MABEBn4s6r6zCgimGfiHg4o0FpNaGv1jGzmqSD ++chsnAiqcV8fQ4Y6p/o0x8CZEXAC+hzdf5w2f1VxzbJaGCTQslmNYo4IBbTCCAWkw ++EwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgQwMB0GA1UdDgQWBBT4x4Lz ++iE6QcS3Qnmz03HNroSojbzAfBgNVHSMEGDAWgBQVMXywjRreZtcVnElSlxckuQF6 ++gzBZBgNVHR8EUjBQME6gTKBKhkhodHRwOi8vdGVzdGNhLmNyeXB0b3Byby5ydS9D ++ZXJ0RW5yb2xsL0NSWVBUTy1QUk8lMjBUZXN0JTIwQ2VudGVyJTIwMi5jcmwwgakG ++CCsGAQUFBwEBBIGcMIGZMGEGCCsGAQUFBzAChlVodHRwOi8vdGVzdGNhLmNyeXB0 ++b3Byby5ydS9DZXJ0RW5yb2xsL3Rlc3QtY2EtMjAxNF9DUllQVE8tUFJPJTIwVGVz ++dCUyMENlbnRlciUyMDIuY3J0MDQGCCsGAQUFBzABhihodHRwOi8vdGVzdGNhLmNy ++eXB0b3Byby5ydS9vY3NwL29jc3Auc3JmMAgGBiqFAwICAwNBAA+nkIdgmqgVr/2J ++FlwzT6GFy4Cv0skv+KuUyfrd7kX4jcY/oGwxpxBv5WfNYDnHrVK90bNsXTqlon2M ++veFd3yM= ++-----END CERTIFICATE----- ++]] ++ local x = openssl.x509.read(certasstring) ++ local t = x:parse() ++ assert(type(t)=='table') ++ --dump(t,0) ++ end ++ ++ function TestIssuer:test141() ++ local c = openssl.cipher.decrypt_new('bf-cbc', "secret_key", "iv") ++ local out = c:update("msg") ++ local final = c:final() ++ c:close() ++ c = nil ++ collectgarbage("collect") ++ end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/9.srp.lua luvi-src-v2.7.6/deps/lua-openssl/test/9.srp.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/9.srp.lua 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/9.srp.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -0,0 +1,63 @@ ++ ++local openssl = require'openssl' ++local srp = openssl.srp ++if srp==nil then ++ print('Skip test srp') ++ return ++end ++ ++local GN = assert(srp.get_default_gN('1024')); ++ ++local self = {} ++ ++TestSRP = {} ++ function TestSRP:setUp() ++ self.user = 'zhaozg' ++ self.pass = 'password' ++ end ++ ++ function TestSRP:tearDown() ++ end ++ ++ function TestSRP:test_1_SRV_CreateVerifier() ++ self.salt, self.verifier = GN:create_verifier(self.user, self.pass) ++ assert(self.salt) ++ assert(self.verifier) ++ end ++ ++ function TestSRP:test_2_SRV_Calc_b() ++ self.Bpub, self.Brnd = GN:calc_b(self.verifier) ++ assert(self.Bpub) ++ assert(self.Brnd) ++ end ++ ++ function TestSRP:test_3_CLI_Calc_a() ++ self.Apub, self.Arnd = GN:calc_a() ++ assert(self.Apub) ++ assert(self.Arnd) ++ end ++ ++ function TestSRP:test_4_Calc_u() ++ self.u = assert(GN:calc_u(self.Apub, self.Bpub)) ++ end ++ ++ function TestSRP:test_5_cli_key() ++ local x = assert(GN.calc_x(self.salt, self.user, self.pass)) ++ self.Kclient = assert(GN:calc_client_key(self.Bpub, x, self.Arnd, self.u)) ++ end ++ ++ function TestSRP:test_6_srv_key() ++ local Kserver = assert(GN:calc_server_key(self.Apub, self.verifier, self.u, self.Brnd)) ++ assert(Kserver==self.Kclient) ++ end ++ ++ function TestSRP:test_7_cli_key() ++ local x = assert(GN.calc_x(self.salt, self.user, self.pass..'1')) ++ self.Kclient = assert(GN:calc_client_key(self.Bpub, x, self.Arnd, self.u)) ++ end ++ ++ function TestSRP:test_8_srv_key() ++ local Kserver = assert(GN:calc_server_key(self.Apub, self.verifier, self.u, self.Brnd)) ++ assert( Kserver~=self.Kclient) ++ end ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/ec.lua luvi-src-v2.7.6/deps/lua-openssl/test/ec.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/ec.lua 2019-02-13 11:31:40.290635288 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/ec.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -14,7 +14,7 @@ testEC = {} + } + local ec = assert(pkey.new(factor)) + +- local pem = assert(ec:export(true)) ++ local pem = assert(ec:export('pem')) + assertEquals(pem,[[ + -----BEGIN PRIVATE KEY----- + MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgH+M5UMX0YRJK6ZLC +@@ -27,7 +27,7 @@ jcWtqOmp3Xyzxw30SJhuUb3l0VdvmZAfnCxqgGpH + function testEC:testEC() + local nec = {'ec','prime256v1'} + local ec = pkey.new(unpack(nec)) +- local t = ec:parse().ec:parse(true) --make basic table ++ local t = ec:parse().ec:parse('pem') --make basic table + assertEquals(type(t.curve_name), 'number') + assertStrContains(t.x.version, 'bn library') + assertStrContains(t.y.version, 'bn library') +@@ -63,5 +63,24 @@ jcWtqOmp3Xyzxw30SJhuUb3l0VdvmZAfnCxqgGpH + ec2p.d = ec:parse().ec:parse().priv_key + local ec2priv = pkey.new(ec2p) + assert(ec2priv:is_private()) ++ end ++ ++ function testEC:testEC() ++ local nec = {'ec','prime256v1'} ++ local key1 = pkey.new(unpack(nec)) ++ local key2 = pkey.new(unpack(nec)) ++ local ec1 = key1:parse().ec ++ local ec2 = key2:parse().ec ++ local secret1 = ec1:compute_key(ec2) ++ local secret2 = ec2:compute_key(ec1) ++ assert(secret1==secret2) ++ ++ local pub1 = pkey.get_public(key1) ++ local pub2 = pkey.get_public(key2) ++ pub1 = pub1:parse().ec ++ pub2 = pub2:parse().ec + ++ secret1 = ec1:compute_key(pub2) ++ secret2 = ec2:compute_key(pub1) ++ assert(secret1==secret2) + end +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/helper.lua luvi-src-v2.7.6/deps/lua-openssl/test/helper.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/helper.lua 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/helper.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -0,0 +1,46 @@ ++local openssl = require'openssl' ++local ext = openssl.x509.extension ++ ++local M = {} ++ ++local default_caexts = { ++ { ++ object='basicConstraints', ++ value='CA:true', ++ critical = true ++ }, ++ { ++ object='keyUsage', ++ value='keyCertSign' ++ } ++} ++ ++function M.to_extensions(exts) ++ exts = exts or default_caexts ++ local ret = {} ++ for i=1, #exts do ++ ret[i] = ext.new_extension(exts[i]) ++ end ++ return ret ++end ++ ++function M.new_ca(subject) ++ --cacert, self sign ++ local pkey = assert(openssl.pkey.new()) ++ local req = assert(openssl.x509.req.new(subject, pkey)) ++ local cacert = openssl.x509.new( ++ 1, --serialNumber ++ req --copy name and extensions ++ ) ++ cacert:extensions(M.to_extensions()) ++ cacert:notbefore(os.time()) ++ cacert:notafter(os.time() + 3600*24*365) ++ assert(cacert:sign(pkey, cacert)) --self sign ++ return pkey, cacert ++end ++ ++M.luaopensslv, M.luav, M.opensslv = openssl.version() ++M.libressl = M.opensslv:find('^LibreSSL') ++ ++return M ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/luacrypto/ca/README luvi-src-v2.7.6/deps/lua-openssl/test/luacrypto/ca/README +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/luacrypto/ca/README 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/luacrypto/ca/README 2019-02-13 11:53:24.321792707 +0100 +@@ -0,0 +1,17 @@ ++Testing x509 certs for luacrypto ++ ++# Make the CA cert ++openssl genrsa -des3 -out ca.key 4096 ++openssl req -new -x509 -days 365 -key ca.key -out ca.crt ++ ++# Make server cert and signing request ++openssl genrsa -des3 -out server.key 4096 ++openssl req -new -key server.key -out server.csr ++ ++# Sign the server csr and generate a crt ++openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt ++ ++# Output unencrypted server key ++openssl rsa -in server.key -out server.key.insecure ++ ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/luv_ssl/ssl_c.lua luvi-src-v2.7.6/deps/lua-openssl/test/luv_ssl/ssl_c.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/luv_ssl/ssl_c.lua 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/luv_ssl/ssl_c.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -1,84 +1,84 @@ +-local uv = require('luv') +-local ssl = require('luv.ssl') ++local uv = require 'luv' ++local ssl = require 'luv.ssl' + ----------------------------------------------- + local count = 0 + local ncount = arg[3] and tonumber(arg[3]) or 40000 + ncount = ncount or 40000 +-local step = 1000/2 ++local step = 1000 / 2 + local tmp = true + +-local function setInterval(fn, ms) ++local function setInterval (fn, ms) + local handle = uv.new_timer() + uv.timer_start(handle, ms, ms, fn) + return handle + end + +-setInterval(function() +- print(os.date(),count) +- print(ssl.error()) +- collectgarbage() +-end, +-1000) ++setInterval(function () ++ print(os.date(), count) ++ print(ssl.error()) ++ collectgarbage() ++ end, 1000) + -------------------------------------------------------------- +-host = arg[1] or "127.0.0.1"; --only ip +-port = arg[2] or "8383"; ++host = arg[1] or "127.0.0.1" --only ip ++port = arg[2] or "8383" + + local address = { +- port = tonumber(port), +- address = host ++ port = tonumber(port), ++ address = host, ++ + } + +-local ctx = ssl.new_ctx({ +- protocol = "TLSv1_2_client", +- verify = {"none"}, +--- options = {"all", "no_sslv2"} +-}) ++local ctx = ssl.new_ctx { ++ protocol = "TLSv1_2_client", ++ verify = ssl.none, ++ -- options = {"all", "no_sslv2"} ++ ++} + + + local new_connection + +-function new_connection(i) ++function new_connection (i) + +- local scli = ssl.connect(address.address,address.port,ctx, function(self) +- count = count + 1 +- self:write('GET / HTTP/1.0\r\n\r\n') +- if tmp then +- self:close() +- end +- +- if count <= ncount then +- new_connection(i) +- end +- +- end) +- +- function scli:ondata(chunk) +- --print(chunk) +- end +- +- function scli:onerror(err) +- print('onerror',err) +- end +- +- function scli:onend() +- --print('onend********8') +- --count = count -1 +- self:close() +- end +- function scli:onclose() +- count = count -1 +- --print('closed') +- end +- return scli ++ local scli = ssl.connect(address.address, address.port, ctx, function (self) ++ count = count + 1 ++ self:write 'GET / HTTP/1.0\r\n\r\n' ++ if tmp then ++ self:close() ++ end ++ ++ if count <= ncount then ++ new_connection(i) ++ end ++ end) ++ ++ function scli:ondata (chunk) ++ --print(chunk) ++ end ++ ++ function scli:onerror (err) ++ print('onerror', err) ++ end ++ ++ function scli:onend () ++ --print('onend********8') ++ --count = count -1 ++ self:close() ++ end ++ function scli:onclose () ++ count = count - 1 ++ --print('closed') ++ end ++ return scli + end + + tmp = true + local conns = {} + +-for i=1, step do +- new_connection(i) ++for i = 1, step do ++ new_connection(i) + end + +-uv.run('default') ++uv.run 'default' + +-print("done") ++print "done" +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/luv_ssl/ssl_s.lua luvi-src-v2.7.6/deps/lua-openssl/test/luv_ssl/ssl_s.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/luv_ssl/ssl_s.lua 2019-02-13 11:31:40.320635083 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/luv_ssl/ssl_s.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -1,83 +1,82 @@ +-local uv = require('luv') +-local ssl = require('luv.ssl') ++local uv = require 'luv' ++local ssl = require 'luv.ssl' + + ----------------------------------------------- + ---[[ + local count = 0 + +-local function setInterval(fn, ms) ++local function setInterval (fn, ms) + local handle = uv.new_timer() + uv.timer_start(handle, ms, ms, fn) + return handle + end + +-setInterval(function() +- print(os.date(),count) +- print(ssl.error()) +- collectgarbage() +-end, +-1000) ++setInterval(function () ++ print(os.date(), count) ++ print(ssl.error()) ++ collectgarbage() ++ end, 1000) + --]] + -------------------------------------------------------------- +-host = arg[1] or "127.0.0.1"; --only ip +-port = arg[2] or "8383"; ++host = arg[1] or "127.0.0.1" --only ip ++port = arg[2] or "8383" + + local address = { +- port = tonumber(port), +- address = host ++ port = tonumber(port), ++ address = host, ++ + } + +-local ctx = ssl.new_ctx({ +- protocol = "TLSv1_2_server", +- verify = {"none"}, +- key = "../luasec/certs/serverAkey.pem", +- certificate = "../luasec/certs/serverA.pem", +- cafile = "../luasec/certs/rootA.pem", +- verify = {"none"}, +--- options = {"all", "no_sslv2"} +-}) ++local ctx = ssl.new_ctx { ++ protocol = "TLSv1_2_server", ++ key = "../luasec/certs/serverAkey.pem", ++ certificate = "../luasec/certs/serverA.pem", ++ cafile = "../luasec/certs/rootA.pem", ++ verify = ssl.none, ++ -- options = {"all", "no_sslv2"} ++ ++} + +-function create_server(host, port, on_connection) ++function create_server (host, port, on_connection) + local server = uv.new_tcp() + uv.tcp_bind(server, host, port) +- uv.listen(server,64, function(self) +- local client = uv.new_tcp() +- uv.accept(server, client) +- on_connection(client) +- end) ++ uv.listen(server, 64, function (self) ++ local client = uv.new_tcp() ++ uv.accept(server, client) ++ on_connection(client) ++ end) + return server + end + + local p = print + local server = create_server(address.address, address.port, function (client) + +- local scli = ssl.new_ssl(ctx,client,true) +- scli:handshake(function(scli) +- print('CONNECTED') +- count = count + 1 +- end) +- +- function scli:ondata(chunk) +- print("ondata", chunk) +- self:close() +- end +- function scli:onerror(err) +- print('onerr',err,ssl.error()) +- end +- +- function scli:onend() +- print("onend") +- uv.shutdown(client, function () +- print("onshutdown") +- uv.close(client) +- end) +- end +- +-end) ++ local scli = ssl.new_ssl(ctx, client, true) ++ scli:handshake(function (scli) ++ print 'CONNECTED' ++ count = count + 1 ++ end) ++ ++ function scli:ondata (chunk) ++ print("ondata", chunk) ++ self:close() ++ end ++ function scli:onerror (err) ++ print('onerr', err, ssl.error()) ++ end ++ ++ function scli:onend () ++ print "onend" ++ uv.shutdown(client, function () ++ print "onshutdown" ++ uv.close(client) ++ end) ++ end ++ end) + + local address = uv.tcp_getsockname(server) + p("server", server, address) + +-uv.run('default') ++uv.run 'default' + +-print("done") ++print "done" +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/sm2.lua luvi-src-v2.7.6/deps/lua-openssl/test/sm2.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/sm2.lua 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/sm2.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -0,0 +1,74 @@ ++local openssl = require'openssl' ++local pkey = openssl.pkey ++local sm2 = openssl.sm2 ++local unpack = unpack or table.unpack ++local helper = require'helper' ++ ++_,_,opensslv = openssl.version(true) ++print(opensslv) ++if opensslv >= 0x10101007 and (not helper.libressl) then ++ print('Support SM2') ++ testSM2 = {} ++ ++ function testSM2:testSM2() ++ local nec = {'ec','SM2'} ++ local ec = pkey.new(unpack(nec)) ++ local t = ec:parse().ec:parse('pem') --make basic table ++ assertEquals(type(t.curve_name), 'number') ++ assertStrContains(t.x.version, 'bn library') ++ assertStrContains(t.y.version, 'bn library') ++ assertStrContains(t.d.version, 'bn library') ++ ++ local k1 = pkey.get_public(ec) ++ assert(not k1:is_private()) ++ local t = k1:parse() ++ assert(t.bits==256) ++ assert(t.type=='ec') ++ assert(t.size==72) ++ local r = t.ec ++ t = r:parse(true) --make basic table ++ assertEquals(type(t.curve_name), 'number') ++ assertStrContains(t.x.version, 'bn library') ++ assertStrContains(t.y.version, 'bn library') ++ assertEquals(t.d, nil) ++ t = r:parse() ++ assertStrContains(tostring(t.pub_key), 'openssl.ec_point') ++ assertStrContains(tostring(t.group), 'openssl.ec_group') ++ local x, y = t.group:affine_coordinates(t.pub_key) ++ assertStrContains(x.version, 'bn library') ++ assertStrContains(y.version, 'bn library') ++ local ec2p = { ++ alg = 'ec', ++ ec_name = t.group:parse().curve_name, ++ x = x, ++ y = y, ++ } ++ local ec2 = pkey.new(ec2p) ++ assert(not ec2:is_private()) ++ ++ ec2p.d = ec:parse().ec:parse().priv_key ++ local ec2priv = pkey.new(ec2p) ++ assert(ec2priv:is_private()) ++ ++ local nec = {'ec','SM2'} ++ local key1 = pkey.new(unpack(nec)) ++ local key2 = pkey.new(unpack(nec)) ++ local ec1 = key1:parse().ec ++ local ec2 = key2:parse().ec ++ local secret1 = ec1:compute_key(ec2) ++ local secret2 = ec2:compute_key(ec1) ++ assert(secret1==secret2) ++ ++ local pub1 = pkey.get_public(key1) ++ local pub2 = pkey.get_public(key2) ++ pub1 = pub1:parse().ec ++ pub2 = pub2:parse().ec ++ ++ secret1 = ec1:compute_key(pub2) ++ secret2 = ec2:compute_key(pub1) ++ assert(secret1==secret2) ++ end ++else ++ print('Skip SM2') ++end ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/test/test.lua luvi-src-v2.7.6/deps/lua-openssl/test/test.lua +--- luvi-src-v2.7.6.orig/deps/lua-openssl/test/test.lua 2019-02-13 11:31:40.293968598 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/test/test.lua 2019-02-13 11:53:24.321792707 +0100 +@@ -3,8 +3,7 @@ EXPORT_ASSERT_TO_GLOBALS = true + require'luaunit' + + openssl.rand_load() +-v = {openssl.version(true)} +-print(openssl.version()) ++print('VERSION:', openssl.version()) + + dofile('0.engine.lua') + dofile('0.misc.lua') +@@ -23,11 +22,15 @@ dofile('5.x509_crl.lua') + dofile('5.x509.lua') + dofile('5.ts.lua') + dofile('6.pkcs7.lua') ++dofile('6.cms.lua') + dofile('7.pkcs12.lua') + dofile('8.ssl_options.lua') + dofile('8.ssl.lua') ++dofile('9.srp.lua') ++dofile('9.issue.lua') + dofile('rsa.lua') + dofile('ec.lua') ++dofile('sm2.lua') + + --LuaUnit.verbosity = 0 + LuaUnit.run() +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/.travis/setenv_lua.sh luvi-src-v2.7.6/deps/lua-openssl/.travis/setenv_lua.sh +--- luvi-src-v2.7.6.orig/deps/lua-openssl/.travis/setenv_lua.sh 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/.travis/setenv_lua.sh 2019-02-13 11:53:24.105128513 +0100 +@@ -1,3 +1,3 @@ +-export PATH=${PATH}:$HOME/.lua:$HOME/.local/bin:${TRAVIS_BUILD_DIR}/install/luarocks/bin ++export PATH=$HOME/.usr/bin:${PATH} + bash .travis/setup_lua.sh +-eval `$HOME/.lua/luarocks path` ++eval `$HOME/.usr/luarocks path` +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/.travis/setup_lua.sh luvi-src-v2.7.6/deps/lua-openssl/.travis/setup_lua.sh +--- luvi-src-v2.7.6.orig/deps/lua-openssl/.travis/setup_lua.sh 2019-02-13 11:31:40.330635015 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/.travis/setup_lua.sh 2019-02-13 11:53:24.105128513 +0100 +@@ -8,16 +8,13 @@ + + set -eufo pipefail + +-LUAJIT_VERSION="2.0.4" ++LUAJIT_VERSION="2.0.5" + LUAJIT_BASE="LuaJIT-$LUAJIT_VERSION" + + source .travis/platform.sh + +-LUA_HOME_DIR=$TRAVIS_BUILD_DIR/install/lua +- +-LR_HOME_DIR=$TRAVIS_BUILD_DIR/install/luarocks +- +-mkdir $HOME/.lua ++LUA_HOME_DIR=$HOME/.usr ++LR_HOME_DIR=$HOME/.usr + + LUAJIT="no" + +@@ -54,10 +51,7 @@ if [ "$LUAJIT" == "yes" ]; then + fi + + make && make install PREFIX="$LUA_HOME_DIR" +- +- ln -s $LUA_HOME_DIR/bin/luajit $HOME/.lua/luajit +- ln -s $LUA_HOME_DIR/bin/luajit $HOME/.lua/lua; +- ++ ln -s $HOME/.usr/bin/luajit $HOME/.usr/bin/lua + else + + if [ "$LUA" == "lua5.1" ]; then +@@ -67,18 +61,14 @@ else + curl http://www.lua.org/ftp/lua-5.2.4.tar.gz | tar xz + cd lua-5.2.4; + elif [ "$LUA" == "lua5.3" ]; then +- curl http://www.lua.org/ftp/lua-5.3.2.tar.gz | tar xz +- cd lua-5.3.2; ++ curl http://www.lua.org/ftp/lua-5.3.4.tar.gz | tar xz ++ cd lua-5.3.4; + fi + + # Build Lua without backwards compatibility for testing + perl -i -pe 's/-DLUA_COMPAT_(ALL|5_2)//' src/Makefile + make $PLATFORM + make INSTALL_TOP="$LUA_HOME_DIR" install; +- +- ln -s $LUA_HOME_DIR/bin/lua $HOME/.lua/lua +- ln -s $LUA_HOME_DIR/bin/luac $HOME/.lua/luac; +- + fi + + cd $TRAVIS_BUILD_DIR +@@ -103,8 +93,6 @@ fi + + make build && make install + +-ln -s $LR_HOME_DIR/bin/luarocks $HOME/.lua/luarocks +- + cd $TRAVIS_BUILD_DIR + + luarocks --version +@@ -118,5 +106,5 @@ elif [ "$LUA" == "lua5.1" ]; then + elif [ "$LUA" == "lua5.2" ]; then + rm -rf lua-5.2.4; + elif [ "$LUA" == "lua5.3" ]; then +- rm -rf lua-5.3.2; ++ rm -rf lua-5.3.4; + fi +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/.travis/setup_ssl.sh luvi-src-v2.7.6/deps/lua-openssl/.travis/setup_ssl.sh +--- luvi-src-v2.7.6.orig/deps/lua-openssl/.travis/setup_ssl.sh 1970-01-01 01:00:00.000000000 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/.travis/setup_ssl.sh 2019-02-13 11:53:24.105128513 +0100 +@@ -0,0 +1,52 @@ ++#!/bin/sh ++if [ -z "$SSL" ]; then ++ echo '$SSL not set, use default openssl' >&2 ++ exit 0 ++fi ++ ++source .travis/platform.sh ++ ++case "$SSL" in ++openssl-0.9.*) ++ SSLURL=https://www.openssl.org/source/old/0.9.x/$SSL.tar.gz ++ ;; ++openssl-1.0.0*) ++ SSLURL=https://www.openssl.org/source/old/1.0.0/$SSL.tar.gz ++ ;; ++openssl-1.0.1*) ++ SSLURL=https://www.openssl.org/source/old/1.0.1/$SSL.tar.gz ++ ;; ++openssl-*) ++ SSLURL=https://www.openssl.org/source/$SSL.tar.gz ++ ;; ++libressl-*) ++ SSLURL=https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/$SSL.tar.gz ++ LIBRESSL=$SSL ++ ;; ++*) ++ echo $SSL where to download? ++ exit 1 ++ ;; ++esac ++ ++if [ ! -d "$HOME/opt/$SSL" ]; then ++ wget "$SSLURL" || exit 1 ++ tar -xzf "$SSL.tar.gz" || exit 1 ++ cd "$SSL" || exit 1 ++ export OPENSSL_DIR=$HOME/.usr ++ if [ "$PLATFORM" == "linux" ]; then ++ ./config shared --prefix="$OPENSSL_DIR" || exit 1 ++ fi ++ if [ "$PLATFORM" == "macosx" ]; then ++ if [ -z "$LIBRESSL" ]; then ++ ./Configure darwin64-x86_64-cc shared --prefix="$OPENSSL_DIR" || exit 1 ++ else ++ ./config --prefix="$OPENSSL_DIR" || exit 1 ++ fi ++ fi ++ make && make install_sw || { rm -rf "$OPENSSL_DIR"; exit 1; } ++ cd .. ++fi ++ ++# vim: ts=8 sw=8 noet tw=79 fen fdm=marker ++ +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl/.travis.yml luvi-src-v2.7.6/deps/lua-openssl/.travis.yml +--- luvi-src-v2.7.6.orig/deps/lua-openssl/.travis.yml 2019-02-13 11:31:40.277302045 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl/.travis.yml 2019-02-13 11:53:24.105128513 +0100 +@@ -3,17 +3,21 @@ language: c + sudo: required + env: + global: +- - LUAROCKS=2.2.2 ++ - LUAROCKS=3.0.3 + matrix: + - LUA=lua5.1 +- - LUA=lua5.2 +- - LUA=lua5.3 +- - LUA=luajit +- ++ - LUA=lua5.1 SSL=openssl-1.0.2p ++ - LUA=lua5.2 SSL=libressl-2.8.0 ++ - LUA=lua5.3 SSL=openssl-1.1.1 ++ - LUA=luajit SSL=openssl-1.1.0i ++ - LUA=luajit2.1 + os: + - linux + - osx + ++matrix: ++ allow_failures: ++ - env: LUA=lua5.2 SSL=libressl-2.8.0 + + branches: + only: +@@ -22,16 +26,20 @@ branches: + before_install: + - source .travis/setenv_lua.sh + - bash .travis/setup_uv.sh ++ - bash .travis/setup_ssl.sh + - git submodule update --init --recursive + - git submodule update --recursive + +-install: +- - sudo $HOME/.lua/luarocks make rockspecs/openssl-scm-1.rockspec ++install: ++ - 'if [[ "$TRAVIS_OS_NAME" == "osx" && -z "$SSL" ]]; then sudo $HOME/.usr/bin/luarocks make openssl-scm-5.rockspec OPENSSL_DIR=/usr/local/opt/openssl; fi' ++ - 'if [[ "$TRAVIS_OS_NAME" == "osx" && -n "$SSL" ]]; then sudo $HOME/.usr/bin/luarocks make openssl-scm-5.rockspec OPENSSL_DIR=$HOME/.usr; fi' ++ - 'if [[ "$TRAVIS_OS_NAME" == "linux" && -z "$SSL" ]]; then sudo -H $HOME/.usr/bin/luarocks make openssl-scm-5.rockspec OPENSSL_DIR=/usr; fi' ++ - 'if [[ "$TRAVIS_OS_NAME" == "linux" && -n "$SSL" ]]; then sudo -H $HOME/.usr/bin/luarocks make openssl-scm-5.rockspec OPENSSL_DIR=$HOME/.usr; fi' + +-script: ++script: + - cd test + - curl https://raw.githubusercontent.com/bluebird75/luaunit/master/luaunit.lua > luaunit.lua +- - lua test.lua ++ - lua -e "package.cpath='../?.so'" test.lua + + notifications: + email: +diff -purN luvi-src-v2.7.6.orig/deps/lua-openssl.cmake luvi-src-v2.7.6/deps/lua-openssl.cmake +--- luvi-src-v2.7.6.orig/deps/lua-openssl.cmake 2019-02-13 11:31:40.273968734 +0100 ++++ luvi-src-v2.7.6/deps/lua-openssl.cmake 2019-02-13 11:49:06.031947286 +0100 +@@ -1,19 +1,32 @@ + set(LUA_OPENSSL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/lua-openssl) ++if(DEFINED ENV{LUA_OPENSSL_DIR}) ++ set(LUA_OPENSSL_DIR $ENV{LUA_OPENSSL_DIR}) ++endif() + + include_directories( +- ${LUA_OPENSSL_DIR}/deps ++ ${LUA_OPENSSL_DIR}/deps/auxiliar ++ ${LUA_OPENSSL_DIR}/deps/lua-compat + ${LUA_OPENSSL_DIR}/src + ) + ++add_definitions( ++ -DCOMPAT52_IS_LUAJIT ++) ++ + if(WIN32) ++ add_definitions( ++ -DWIN32_LEAN_AND_MEAN ++ -D_CRT_SECURE_NO_WARNINGS ++ ) + else() + find_package(Threads) + add_definitions(-DPTHREADS) + endif() + + add_library(lua_openssl ++ ${LUA_OPENSSL_DIR}/deps/auxiliar/auxiliar.c ++ ${LUA_OPENSSL_DIR}/deps/auxiliar/subsidiar.c + ${LUA_OPENSSL_DIR}/src/asn1.c +- ${LUA_OPENSSL_DIR}/src/auxiliar.c + ${LUA_OPENSSL_DIR}/src/bio.c + ${LUA_OPENSSL_DIR}/src/callback.c + ${LUA_OPENSSL_DIR}/src/cipher.c +@@ -40,6 +53,7 @@ add_library(lua_openssl + ${LUA_OPENSSL_DIR}/src/private.h + ${LUA_OPENSSL_DIR}/src/rsa.c + ${LUA_OPENSSL_DIR}/src/sk.h ++ ${LUA_OPENSSL_DIR}/src/srp.c + ${LUA_OPENSSL_DIR}/src/ssl.c + ${LUA_OPENSSL_DIR}/src/th-lock.c + ${LUA_OPENSSL_DIR}/src/util.c +@@ -52,7 +66,7 @@ add_library(lua_openssl + ) + + set_target_properties(lua_openssl PROPERTIES +- COMPILE_FLAGS "-DLUA_LIB -DCOMPAT52_IS_LUAJIT") ++ COMPILE_FLAGS "-DLUA_LIB") + + if (WithSharedOpenSSL) + target_link_libraries(lua_openssl ssl crypto)