From deed39a1fb62edcb79b357d023158dfd7f810401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Diot?= Date: Wed, 28 Jun 2023 11:35:25 -0400 Subject: [PATCH] Update lua-resty-openssl to version 0.8.23 --- src/deps/clone.sh | 4 +- .../.github/workflows/tests.yml | 49 ++++++---- src/deps/src/lua-resty-openssl/CHANGELOG.md | 12 ++- src/deps/src/lua-resty-openssl/README.md | 40 ++++++-- .../examples/perf/framework.lua | 93 +++++++++++++++++++ .../examples/perf/test_cipher.lua | 49 ++++++++++ .../examples/perf/test_pkey_asymm.lua | 64 +++++++++++++ .../examples/perf/test_pkey_codec.lua | 33 +++++++ .../examples/perf/test_x509_codec.lua | 23 +++++ .../lua-resty-openssl/lib/resty/openssl.lua | 2 +- .../lib/resty/openssl/include/x509_vfy.lua | 21 +++++ .../lib/resty/openssl/pkcs12.lua | 6 +- .../lib/resty/openssl/x509/altname.lua | 5 +- .../lib/resty/openssl/x509/chain.lua | 5 +- .../openssl/x509/extension/dist_points.lua | 10 +- .../openssl/x509/extension/info_access.lua | 5 +- .../lib/resty/openssl/x509/extensions.lua | 11 ++- .../lib/resty/openssl/x509/store.lua | 56 ++++++++++- ...ec => lua-resty-openssl-0.8.23-1.rockspec} | 4 +- 19 files changed, 449 insertions(+), 43 deletions(-) create mode 100644 src/deps/src/lua-resty-openssl/examples/perf/framework.lua create mode 100644 src/deps/src/lua-resty-openssl/examples/perf/test_cipher.lua create mode 100644 src/deps/src/lua-resty-openssl/examples/perf/test_pkey_asymm.lua create mode 100644 src/deps/src/lua-resty-openssl/examples/perf/test_pkey_codec.lua create mode 100644 src/deps/src/lua-resty-openssl/examples/perf/test_x509_codec.lua rename src/deps/src/lua-resty-openssl/{lua-resty-openssl-0.8.22-1.rockspec => lua-resty-openssl-0.8.23-1.rockspec} (99%) diff --git a/src/deps/clone.sh b/src/deps/clone.sh index d8dc2114d..823643784 100755 --- a/src/deps/clone.sh +++ b/src/deps/clone.sh @@ -254,13 +254,13 @@ git_secure_clone "https://github.com/bungle/lua-resty-template.git" "c08c6bc9e27 echo "ℹ️ Downloading lua-resty-lock" git_secure_clone "https://github.com/openresty/lua-resty-lock.git" "9dc550e56b6f3b1a2f1a31bb270a91813b5b6861" -# lua-resty-openssl v0.8.22 +# lua-resty-openssl v0.8.23 echo "ℹ️ Downloading lua-resty-openssl" dopatch="no" if [ ! -d "deps/src/lua-resty-openssl" ] ; then dopatch="yes" fi -git_secure_clone "https://github.com/fffonion/lua-resty-openssl.git" "484907935e60273d31626ac849b23a2d218173de" +git_secure_clone "https://github.com/fffonion/lua-resty-openssl.git" "b23c072a405b749ac60d21e3946cbf57a959b780" if [ "$dopatch" == "yes" ] ; then do_and_check_cmd rm -r deps/src/lua-resty-openssl/t fi diff --git a/src/deps/src/lua-resty-openssl/.github/workflows/tests.yml b/src/deps/src/lua-resty-openssl/.github/workflows/tests.yml index 40877a452..6209890c3 100644 --- a/src/deps/src/lua-resty-openssl/.github/workflows/tests.yml +++ b/src/deps/src/lua-resty-openssl/.github/workflows/tests.yml @@ -23,47 +23,48 @@ jobs: runs-on: ubuntu-22.04 strategy: + fail-fast: false matrix: include: # TODO: arm64 - # latest and one version older for valgrind + # latest and one version older for valgrind and perf test - nginx: "1.19.9" openssl: "1.0.2u" - valgrind: "valgrind" + extras: "valgrind" lua_nginx_module: "v0.10.20" lua_resty_core: "v0.1.22" - nginx: "1.19.9" - openssl: "1.1.1s" - valgrind: "valgrind" + openssl: "1.1.1t" + extras: "valgrind" lua_nginx_module: "v0.10.20" lua_resty_core: "v0.1.22" - nginx: "1.19.9" openssl: "3.0.8" - valgrind: "valgrind" + extras: "valgrind" openssl_opts: "enable-fips" lua_nginx_module: "v0.10.20" lua_resty_core: "v0.1.22" nginx_cc_opts: "-Wno-error" - nginx: "1.21.4" openssl: "1.0.2u" - valgrind: "valgrind" + extras: "valgrind" lua_nginx_module: "v0.10.21" lua_resty_core: "v0.1.23" - nginx: "1.21.4" - openssl: "1.1.1s" - valgrind: "valgrind" + openssl: "1.1.1t" + extras: "valgrind perf" lua_nginx_module: "v0.10.21" lua_resty_core: "v0.1.23" - nginx: "1.21.4" openssl: "3.0.8" - valgrind: "valgrind" + extras: "valgrind perf" openssl_opts: "enable-fips" lua_nginx_module: "v0.10.21" lua_resty_core: "v0.1.23" nginx_cc_opts: "-Wno-error" - nginx: "1.21.4" - openssl: "3.1.0-beta1" - valgrind: "valgrind" + openssl: "3.1.0" + extras: "valgrind perf" openssl_opts: "enable-fips" lua_nginx_module: "v0.10.21" lua_resty_core: "v0.1.23" @@ -78,17 +79,17 @@ jobs: openssl: "1.0.2u" fips2: "2.0.16" openssl_opts: "fips --with-fipsdir=/home/runner/work/cache/ssl/fips" - valgrind: "valgrind" + extras: "valgrind" lua_nginx_module: "v0.10.21" lua_resty_core: "v0.1.23" - nginx: "1.21.4" boringssl: "ae223d6138807a13006342edfeef32e813246b39" # fips-20190808 - valgrind: "valgrind" + extras: "valgrind perf" lua_nginx_module: "v0.10.21" lua_resty_core: "v0.1.23" - nginx: "1.21.4" boringssl: "853ca1ea1168dff08011e5d42d94609cc0ca2e27" # fips-20210429, not active yet - valgrind: "valgrind" + extras: "valgrind perf" lua_nginx_module: "v0.10.21" lua_resty_core: "v0.1.23" @@ -204,7 +205,7 @@ jobs: env: LUAJIT_CC_OPTS: ${{ matrix.luajit_cc_opts }} run: | - if [ "X${{ matrix.valgrind }}" != "X" ]; then LUAJIT_CC_OPTS="$LUAJIT_CC_OPTS -DLUAJIT_NUMMODE=2 -DLUAJIT_${{ matrix.valgrind }} -DLUAJIT_USE_SYSMALLOC -O0"; fi + if [[ "${{ matrix.extras }}" == *valgrind* ]]; then LUAJIT_CC_OPTS="$LUAJIT_CC_OPTS -DLUAJIT_NUMMODE=2 -DLUAJIT_USE_SYSMALLOC -O0"; fi export cd $LUAJIT_PREFIX if [ ! -e luajit2 ]; then git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git; fi @@ -221,7 +222,7 @@ jobs: env: NGINX_CC_OPTS: ${{ matrix.nginx_cc_opts }} run: | - if [ "X${{ matrix.valgrind }}" != "X" ]; then NGINX_CC_OPTS="$NGINX_CC_OPTS -O0"; fi + if [[ "${{ matrix.extras }}" == *valgrind* ]]; then NGINX_CC_OPTS="$NGINX_CC_OPTS -O0"; fi export PATH=$BASE_PATH/work/nginx/sbin:$BASE_PATH/../nginx-devel-utils:$PATH export LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH export NGX_LUA_LOC=$BASE_PATH/../lua-nginx-module @@ -232,6 +233,20 @@ jobs: nginx -V ldd `which nginx`|grep -E 'luajit|ssl|pcre' + - name: Run performance test + if: contains(matrix.extras, 'perf') + run: | + wget https://github.com/openresty/resty-cli/raw/master/bin/resty + chmod +x resty + + export LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH + export PATH=$BASE_PATH/work/nginx/sbin:$PATH + + for f in $(find examples/perf -type f -name "test_*" | sort); do + ./resty --no-stream -I lib $f + echo '================================================================' + done + - name: Run Test run: | export LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH @@ -243,7 +258,7 @@ jobs: TEST_NGINX_TIMEOUT=10 prove -j$JOBS t/openssl/ssl/ 2>&1 - name: Run Valgrind - if: matrix.valgrind != '' + if: contains(matrix.extras, 'valgrind') run: | export LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH export TEST_NGINX_VALGRIND='--num-callers=100 -q --tool=memcheck --leak-check=full --show-possibly-lost=no --gen-suppressions=all --suppressions=valgrind.suppress --track-origins=yes' TEST_NGINX_TIMEOUT=60 TEST_NGINX_SLEEP=1 diff --git a/src/deps/src/lua-resty-openssl/CHANGELOG.md b/src/deps/src/lua-resty-openssl/CHANGELOG.md index 0aadc4dfe..bde3cec8b 100644 --- a/src/deps/src/lua-resty-openssl/CHANGELOG.md +++ b/src/deps/src/lua-resty-openssl/CHANGELOG.md @@ -2,6 +2,15 @@ ## [Unreleased] + +## [0.8.23] - 2023-06-20 +### bug fixes +- **\*:** fix typos and add error check for new_of/dup_of ([#2](https://github.com/fffonion/lua-resty-openssl/issues/2)) [aa6ad47](https://github.com/fffonion/lua-resty-openssl/commit/aa6ad4707845cca9c46282a1550bb9fee7d48698) + +### features +- **tests:** add performance test ([#112](https://github.com/fffonion/lua-resty-openssl/issues/112)) [100b4e4](https://github.com/fffonion/lua-resty-openssl/commit/100b4e43843a597327be6e5356c64b5ce621fa56) + + ## [0.8.22] - 2023-04-26 ### bug fixes @@ -497,7 +506,8 @@ - **x509:** export pubkey [ede4f81](https://github.com/fffonion/lua-resty-openssl/commit/ede4f817cb0fe092ad6f9ab5d6ecdcde864a9fd8) -[Unreleased]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.22...HEAD +[Unreleased]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.23...HEAD +[0.8.23]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.22...0.8.23 [0.8.22]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.21...0.8.22 [0.8.21]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.20...0.8.21 [0.8.20]: https://github.com/fffonion/lua-resty-openssl/compare/0.8.19...0.8.20 diff --git a/src/deps/src/lua-resty-openssl/README.md b/src/deps/src/lua-resty-openssl/README.md index 24e805514..2192f4246 100644 --- a/src/deps/src/lua-resty-openssl/README.md +++ b/src/deps/src/lua-resty-openssl/README.md @@ -248,6 +248,7 @@ Table of Contents + [store:set_depth](#storeset_depth) + [store:set_flags](#storeset_flags) + [store:verify](#storeverify) + + [store:check_revocation](#storecheck_revocation) * [resty.openssl.x509.revoked](#restyopensslx509revoked) + [revoked.new](#revokednew) + [revoked.istype](#revokedistype) @@ -294,7 +295,7 @@ Description =========== `lua-resty-openssl` is a FFI-based OpenSSL binding library, currently -supports OpenSSL `3.0.0`, `1.1.1`, `1.1.0` and `1.0.2` series. +supports OpenSSL `3.1.x`, `3.0.x`, `1.1.1`, `1.1.0` and `1.0.2` series. **Note: when using with OpenSSL 1.0.2, it's recommanded to not use this library with other FFI-based OpenSSL binding libraries to avoid potential mismatch of `cdef`.** @@ -411,13 +412,13 @@ lua-resty-openssl supports following modes: Compile the module per [security policy](https://www.openssl.org/docs/fips/SecurityPolicy-2.0.2.pdf), -**OpenSSL 3.0.0 fips provider (haven't certified)** +**OpenSSL 3.0.0 fips provider ** Refer to https://wiki.openssl.org/index.php/OpenSSL_3.0 Section 7 Compile the provider per guide, install the fipsmodule.cnf that matches hash of FIPS provider fips.so. -On OpenSSL 3.0, this function also turns on and off default +On OpenSSL 3.0 or later, this function also turns on and off default properties for EVP functions. When turned on, all applications using EVP_* API will be redirected to FIPS-compliant implementations and have no access to non-FIPS-compliant algorithms. @@ -510,7 +511,7 @@ A module to provide OSSL_LIB_CTX context switches. OSSL_LIB_CTX is an internal OpenSSL library context type. Applications may allocate their own, but may also use NULL to use a default context with functions that take an OSSL_LIB_CTX argument. See [OSSL_LIB_CTX.3](#https://www.openssl.org/docs/manmaster/man3/OSSL_LIB_CTX.html) for deeper -reading. It can be used to replace `ENGINE` in prior 3.0 world. +reading. The context is currently effective following modules: @@ -524,7 +525,7 @@ The context is currently effective following modules: - [rand](#restyopensslrand) - [x509](#restyopensslx509), [x509.csr](#restyopensslx509csr), [x509.crl](#restyopensslx509crl) and some [x509.store](#restyopensslx509store) functions -This module is only available on OpenSSL 3.0. +This module is only available on OpenSSL 3.0 or later. [Back to TOC](#table-of-contents) @@ -634,7 +635,7 @@ for explanation of each type. ```lua local version = require("resty.openssl.version") -ngx.say(version.version(version.INFO_DSO_EXTENSION)) +ngx.say(version.info(version.INFO_DSO_EXTENSION)) -- outputs ".so" ``` @@ -646,7 +647,7 @@ A boolean indicates whether the linked OpenSSL is 3.x series. [Back to TOC](#table-of-contents) -### version.OPENSSL_3X +### version.OPENSSL_30 Deprecated: use `version.OPENSSL_3X` is encouraged. @@ -3813,12 +3814,16 @@ to explictly select provider to fetch algorithms. ### store:add -**syntax**: *ok, err = store:add(x509_or_crl)* +**syntax**: *ok, err = store:add(x509_or_crl, skip_set_crl_check_flags?)* Adds a X.509 or a CRL object into store. The argument must be a [resty.openssl.x509](#restyopensslx509) instance or a [resty.openssl.x509.crl](#restyopensslx509crl) instance. +By default, adding a CRL object will automatically set the flag to store +`X509_V_FLAG_CRL_CHECK`. Setting the second optional argument to `true` will +skip settting the flags. + [Back to TOC](#table-of-contents) ### store:load_file @@ -3947,6 +3952,25 @@ for all available flags. [Back to TOC](#table-of-contents) +### store:check_revocation + +**syntax**: *ok, err = store:check_revocation(verified_chain, properties?)* + +Only does the revocation check. The first argument `verified_chain` must be a +[resty.openssl.x509.chain](#restyopensslx509chain) instance which could be returned from +`store_ctx:verify` or be built by yourself. Note the first cert needs to be the end entity +certificate you want to check and the second cert needs to be its issuer. + +Staring from OpenSSL 3.0, this function accepts an optional `properties` parameter +to explictly select provider to fetch algorithms. + +Returns `true` when the certificate isn't revoked, +otherwise returns `nil` and error explaining the reason. + +Note this function is supported from OpenSSL 1.1.0 and not supported in BoringSSL. + +[Back to TOC](#table-of-contents) + ## resty.openssl.x509.revoked Module to interact with X509_REVOKED. diff --git a/src/deps/src/lua-resty-openssl/examples/perf/framework.lua b/src/deps/src/lua-resty-openssl/examples/perf/framework.lua new file mode 100644 index 000000000..eb22a2841 --- /dev/null +++ b/src/deps/src/lua-resty-openssl/examples/perf/framework.lua @@ -0,0 +1,93 @@ +local ffi = require "ffi" +local C = ffi.C +local ITER = 2000 + +local get_duration +do + ffi.cdef [[ + + typedef long time_t; + typedef int clockid_t; + typedef struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ + } nanotime; + + int clock_gettime(clockid_t clk_id, struct timespec *tp); + + ]] + local time_ns + do + local nanop = ffi.new("nanotime[1]") + function time_ns() + -- CLOCK_REALTIME -> 0 + C.clock_gettime(0, nanop) + local t = nanop[0] + + return tonumber(t.tv_sec) * 1e9 + tonumber(t.tv_nsec) + end + end + + local last = 0 + get_duration = function() + local n = time_ns() + local d = n - last + last = n + return d + end +end + +local function hmt(t) + if t > 1e9 * 0.01 then + return string.format("%.3f s", t/1e9) + elseif t > 1e6 * 0.01 then + return string.format("%.3f ms", t/1e6) + else + return string.format("%d ns", t) + end +end + +-- return sum, avg, max +local function stat(t) + if not t then + return 0, 0, 0 + end + + local v = 0 + local max = 0 + for _, i in ipairs(t) do + v = v + i + if i > max then + max = i + end + end + return v, v/#t, max +end + +local function test(desc, r, iter) + print("RUNNING " .. ITER .. " ITERATIONS FOR " .. desc) + local data = table.new(ITER, 0) + for i=1, ITER do + get_duration() + local ok, err = r() + data[i] = get_duration() + assert(ok, err) + end + + local sum, avg, max = stat(data) + + print(string.format("FINISHED in\t%s (%d op/s)\nAVG\t%s\tMAX\t%s", hmt(sum), 1e9/avg, hmt(avg), hmt(max))) + print(string.rep("-", 64)) +end + +local function set_iteration(i) + ITER = i +end + +print("LOADING TEST FROM " .. arg[0]) +print(string.rep("=", 64)) + +return { + test = test, + set_iteration = set_iteration, +} diff --git a/src/deps/src/lua-resty-openssl/examples/perf/test_cipher.lua b/src/deps/src/lua-resty-openssl/examples/perf/test_cipher.lua new file mode 100644 index 000000000..fc2245665 --- /dev/null +++ b/src/deps/src/lua-resty-openssl/examples/perf/test_cipher.lua @@ -0,0 +1,49 @@ +local path = debug.getinfo(1, "S").source:sub(2):match("(.*/)") +package.path = path .. "/?.lua;" .. package.path + +local test = require "framework".test +local set_iteration = require "framework".set_iteration +local cipher = require "resty.openssl.cipher" +local version = require("resty.openssl.version") + +local key = string.rep("0", 32) +local iv = string.rep("0", 16) +local data = string.rep("1", 4096) +local aad = string.rep("2", 10) + +set_iteration(100000) + +for _, t in ipairs({"aes-256-cbc", "aes-256-gcm", "chacha20-poly1305"}) do + for _, op in ipairs({"encrypt", "decrypt"}) do + -- the fips version of boringssl we used seems don't have chacha20 + if t == "chacha20-poly1305" and (not version.OPENSSL_111_OR_LATER or version.BORINGSSL) then + goto continue + end + + local c = assert(cipher.new(t)) + local _iv = iv + local _aad + if t == "aes-256-gcm" or t == "chacha20-poly1305" then + _iv = string.rep("0", 12) + _aad = aad + end + + if op == "encrypt" then + test("encrypt with " .. t .. " on " .. #data .. " bytes", function() + return c:encrypt(key, _iv, data, false, _aad) + end) + + else + local ciphertext = assert(c:encrypt(key, _iv, data, false, _aad)) + + local tag + if t == "aes-256-gcm" or t == "chacha20-poly1305" then + tag = assert(c:get_aead_tag()) + end + test("decrypt with " .. t .. " on " .. #ciphertext .. " bytes", function() + return c:decrypt(key, _iv, ciphertext, false, _aad, tag) + end) + end +::continue:: + end +end diff --git a/src/deps/src/lua-resty-openssl/examples/perf/test_pkey_asymm.lua b/src/deps/src/lua-resty-openssl/examples/perf/test_pkey_asymm.lua new file mode 100644 index 000000000..c153e7c4f --- /dev/null +++ b/src/deps/src/lua-resty-openssl/examples/perf/test_pkey_asymm.lua @@ -0,0 +1,64 @@ +local path = debug.getinfo(1, "S").source:sub(2):match("(.*/)") +package.path = path .. "/?.lua;" .. package.path + +local test = require "framework".test +local set_iteration = require "framework".set_iteration +local pkey = require "resty.openssl.pkey" +local version = require("resty.openssl.version") +local data = string.rep("=", 200) + +set_iteration(1000) + +local rsa = pkey.new({ type = "RSA", bits = 4096 }) + +for _, op in ipairs({"encrypt", "decrypt"}) do + if op == "encrypt" then + test("encrypt with RSA on " .. #data .. " bytes", function() + return rsa:encrypt(data) + end) + + else + + local ciphertext = assert(rsa:encrypt(data)) + test("decrypt with RSA on " .. #ciphertext .. " bytes", function() + return rsa:decrypt(ciphertext) + end) + end +end + + +for _, t in ipairs({"RSA", "EC", "Ed25519", "Ed448"}) do + for _, op in ipairs({"sign", "verify"}) do + -- the fips version of boringssl we used seems don't have ed448 + if (t == "Ed25519" and not version.OPENSSL_111_OR_LATER) or (t == "Ed448" and version.BORINGSSL) then + goto continue + end + + local opts = { type = t } + if t == "EC" then + opts.curve = "prime256v1" + elseif t == "RSA" then + opts.bits = 4096 + end + + local c = assert(pkey.new(opts)) + local md_alg + if t == "RSA" or t == "EC" then + md_alg = "SHA256" + end + + if op == "sign" then + test("sign with " .. t .. (md_alg and ("-" .. md_alg) or "") .. " on " .. #data .. " bytes", function() + return c:sign(data, md_alg) + end) + + else + local sig = assert(c:sign(data, md_alg)) + + test("verify with " .. t .. (md_alg and ("-" .. md_alg) or "") .. " on " .. #data .. " bytes", function() + return c:verify(sig, data, md_alg) + end) + end +::continue:: + end +end diff --git a/src/deps/src/lua-resty-openssl/examples/perf/test_pkey_codec.lua b/src/deps/src/lua-resty-openssl/examples/perf/test_pkey_codec.lua new file mode 100644 index 000000000..973b8bb59 --- /dev/null +++ b/src/deps/src/lua-resty-openssl/examples/perf/test_pkey_codec.lua @@ -0,0 +1,33 @@ +local path = debug.getinfo(1, "S").source:sub(2):match("(.*/)") +package.path = path .. "/?.lua;" .. package.path + +local test = require "framework".test +local pkey = require "resty.openssl.pkey" +local example_pkey = assert(pkey.new()) + +for _, op in ipairs({"load", "export"}) do + for _, t in ipairs({"PEM", "DER", "JWK"}) do + for _, p in ipairs({"public", "private"}) do + + if op == "load" then + local txt = assert(example_pkey:tostring(p, t)) + local opts = { + format = t, + } + if t ~= "JWK" then + opts.type = p == "public" and "pu" or "pr" + end + + test("load " .. t .. " " .. p .. " key", function() + return pkey.new(txt, opts) + end) + + else + test("export " .. t .. " " .. p .. " key", function() + return example_pkey:tostring(p, t) + end) + end + + end + end +end diff --git a/src/deps/src/lua-resty-openssl/examples/perf/test_x509_codec.lua b/src/deps/src/lua-resty-openssl/examples/perf/test_x509_codec.lua new file mode 100644 index 000000000..abc74df52 --- /dev/null +++ b/src/deps/src/lua-resty-openssl/examples/perf/test_x509_codec.lua @@ -0,0 +1,23 @@ +local path = debug.getinfo(1, "S").source:sub(2):match("(.*/)") +package.path = path .. "/?.lua;" .. package.path + +local test = require "framework".test +local x509 = require "resty.openssl.x509" +local cert = assert(io.open(path .. "../../t/fixtures/Github.pem")):read("*a") +local example_x509 = assert(x509.new(cert)) + +for _, op in ipairs({"load", "export"}) do + for _, t in ipairs({"PEM", "DER"}) do + if op == "load" then + local txt = assert(example_x509:tostring(t)) + test("load " .. t .. " x509", function() + return x509.new(txt, t) + end) + + else + test("export " .. t .. " x509", function() + return example_x509:tostring(t) + end) + end + end +end diff --git a/src/deps/src/lua-resty-openssl/lib/resty/openssl.lua b/src/deps/src/lua-resty-openssl/lib/resty/openssl.lua index d8b153ab8..9ef11ffd5 100644 --- a/src/deps/src/lua-resty-openssl/lib/resty/openssl.lua +++ b/src/deps/src/lua-resty-openssl/lib/resty/openssl.lua @@ -25,7 +25,7 @@ try_require_modules() local _M = { - _VERSION = '0.8.22', + _VERSION = '0.8.23', } local libcrypto_name diff --git a/src/deps/src/lua-resty-openssl/lib/resty/openssl/include/x509_vfy.lua b/src/deps/src/lua-resty-openssl/lib/resty/openssl/include/x509_vfy.lua index 92c95e5aa..54317f603 100644 --- a/src/deps/src/lua-resty-openssl/lib/resty/openssl/include/x509_vfy.lua +++ b/src/deps/src/lua-resty-openssl/lib/resty/openssl/include/x509_vfy.lua @@ -6,6 +6,7 @@ require "resty.openssl.include.stack" local OPENSSL_10 = require("resty.openssl.version").OPENSSL_10 local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL = require("resty.openssl.version").BORINGSSL local BORINGSSL_110 = require("resty.openssl.version").BORINGSSL_110 ffi.cdef [[ @@ -38,6 +39,11 @@ ffi.cdef [[ void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); + int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); + + // STACK_OF(X509_CRL) + void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, OPENSSL_STACK *sk); + int X509_PURPOSE_get_by_sname(char *sname); X509_PURPOSE *X509_PURPOSE_get0(int idx); int X509_PURPOSE_get_id(const X509_PURPOSE *xp); @@ -80,10 +86,25 @@ elseif OPENSSL_11_OR_LATER then ffi.cdef [[ // STACK_OF(X509) OPENSSL_STACK *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); + typedef int (*X509_STORE_CTX_check_revocation_fn)(X509_STORE_CTX *ctx); + // STACK_OF(X509) + void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, OPENSSL_STACK *sk); ]]; _M.X509_STORE_CTX_get0_chain = C.X509_STORE_CTX_get0_chain end +-- these two apis are supported from 1.1.0 but not supported by boringssl +if not BORINGSSL then + if OPENSSL_11_OR_LATER then + ffi.cdef [[ + typedef int (*X509_STORE_CTX_check_revocation_fn)(X509_STORE_CTX *ctx); + X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(const X509_STORE_CTX *ctx); + // STACK_OF(X509) + void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, OPENSSL_STACK *sk); + ]]; + end +end + if OPENSSL_3X then ffi.cdef [[ X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq); diff --git a/src/deps/src/lua-resty-openssl/lib/resty/openssl/pkcs12.lua b/src/deps/src/lua-resty-openssl/lib/resty/openssl/pkcs12.lua index 6e3b216f5..222bce2dc 100644 --- a/src/deps/src/lua-resty-openssl/lib/resty/openssl/pkcs12.lua +++ b/src/deps/src/lua-resty-openssl/lib/resty/openssl/pkcs12.lua @@ -41,6 +41,10 @@ local function decode(p12, passphrase) local px509 = ptr_ptr_of_x509() local pstack = ptr_ptr_of_stack() local stack = stack_of_x509_new() + if stack == nil then + return nil, "pkcs12.decode: OPENSSL_sk_new_null() failed" + end + -- assign a valid OPENSSL_STACK so gc is taken care of pstack[0] = stack @@ -165,4 +169,4 @@ return { loads = decode, encode = encode, dumps = encode, -} \ No newline at end of file +} diff --git a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/altname.lua b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/altname.lua index 34bf9e044..230c43b4c 100644 --- a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/altname.lua +++ b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/altname.lua @@ -115,7 +115,10 @@ function _M.dup(ctx) return nil, "x509.altname.dup: expect a GENERAL_NAMES* ctx at #1" end - local dup_ctx = dup(ctx) + local dup_ctx, err = dup(ctx) + if dup_ctx == nil then + return nil, err + end return setmetatable({ cast = ffi_cast("GENERAL_NAMES*", dup_ctx), diff --git a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/chain.lua b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/chain.lua index 5557ea0d8..ef4d258c6 100644 --- a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/chain.lua +++ b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/chain.lua @@ -17,7 +17,10 @@ local add = stack_lib.add_of(STACK) local mt = stack_lib.mt_of(STACK, x509_lib.dup, _M) function _M.new() - local raw = new() + local raw, err = new() + if raw == nil then + return nil, err + end local self = setmetatable({ stack_of = STACK, diff --git a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extension/dist_points.lua b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extension/dist_points.lua index b1d419be9..5113a6c2f 100644 --- a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extension/dist_points.lua +++ b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extension/dist_points.lua @@ -27,6 +27,7 @@ function _M.new() end local self = setmetatable({ + stack_of = STACK, ctx = ctx, _is_shallow_copy = false, }, mt) @@ -35,16 +36,21 @@ function _M.new() end function _M.istype(l) - return l and l.cast and ffi.istype(stack_ptr_ct, l.cast) + return l and l.ctx and ffi.istype(stack_ptr_ct, l.ctx) + and l.stack_of and l.stack_of == STACK end function _M.dup(ctx) if ctx == nil or not ffi.istype(stack_ptr_ct, ctx) then return nil, "expect a stack ctx at #1" end - local dup_ctx = dup(ctx) + local dup_ctx, err = dup(ctx) + if dup_ctx == nil then + return nil, err + end return setmetatable({ + stack_of = STACK, ctx = dup_ctx, -- don't let lua gc the original stack to keep its elements _dupped_from = ctx, diff --git a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extension/info_access.lua b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extension/info_access.lua index 21025a8e3..dce97e97d 100644 --- a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extension/info_access.lua +++ b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extension/info_access.lua @@ -59,7 +59,10 @@ function _M.dup(ctx) if ctx == nil or not ffi.istype(authority_info_access_ptr_ct, ctx) then return nil, "expect a AUTHORITY_INFO_ACCESS* ctx at #1" end - local dup_ctx = dup(ctx) + local dup_ctx, err = dup(ctx) + if dup_ctx == nil then + return nil, err + end return setmetatable({ ctx = dup_ctx, diff --git a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extensions.lua b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extensions.lua index 3b64b8a19..6f0c085e5 100644 --- a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extensions.lua +++ b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/extensions.lua @@ -17,7 +17,10 @@ local dup = stack_lib.dup_of(STACK) local mt = stack_lib.mt_of(STACK, extension_lib.dup, _M) function _M.new() - local raw = new() + local raw, err = new() + if raw == nil then + return nil, err + end local self = setmetatable({ stack_of = STACK, @@ -37,9 +40,13 @@ function _M.dup(ctx) return nil, "x509.extensions.dup: expect a stack ctx at #1, got " .. type(ctx) end - local dup_ctx = dup(ctx) + local dup_ctx, err = dup(ctx) + if dup_ctx == nil then + return nil, err + end return setmetatable({ + stack_of = STACK, ctx = dup_ctx, -- don't let lua gc the original stack to keep its elements _dupped_from = ctx, diff --git a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/store.lua b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/store.lua index 95a3848e0..3a0bffb3d 100644 --- a/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/store.lua +++ b/src/deps/src/lua-resty-openssl/lib/resty/openssl/x509/store.lua @@ -9,14 +9,17 @@ local x509_lib = require "resty.openssl.x509" local chain_lib = require "resty.openssl.x509.chain" local crl_lib = require "resty.openssl.x509.crl" local ctx_lib = require "resty.openssl.ctx" -local format_error = require("resty.openssl.err").format_all_error -local format_all_error = require("resty.openssl.err").format_error +local format_all_error = require("resty.openssl.err").format_all_error +local format_error = require("resty.openssl.err").format_error +local OPENSSL_11_OR_LATER = require("resty.openssl.version").OPENSSL_11_OR_LATER local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X +local BORINGSSL = require("resty.openssl.version").BORINGSSL local _M = {} local mt = { __index = _M } _M.verify_flags = x509_vfy_macro.verify_flags +local flag_crl_check = _M.verify_flags.X509_V_FLAG_CRL_CHECK local x509_store_ptr_ct = ffi.typeof('X509_STORE*') @@ -47,7 +50,7 @@ function _M:use_default(properties) return true end -function _M:add(item) +function _M:add(item, skip_set_flags) local dup local err if x509_lib.istype(item) then @@ -75,7 +78,7 @@ function _M:add(item) -- enables CRL checking for the certificate chain leaf certificate. -- An error occurs if a suitable CRL cannot be found. -- Note: this does not check for certificates in the chain. - if C.X509_STORE_set_flags(self.ctx, 0x4) ~= 1 then + if not skip_set_flags and C.X509_STORE_set_flags(self.ctx, 0x4) ~= 1 then return false, format_error("x509.store:add: X509_STORE_set_flags") end -- decrease the dup ctx ref count immediately to make leak test happy @@ -228,4 +231,49 @@ function _M:verify(x509, chain, return_chain, properties, verify_method, flags) end +function _M:check_revocation(verified_chain, properties) + if BORINGSSL then + return nil, "x509.store:check_revocation: this API is not supported in BoringSSL" + end + + if not OPENSSL_11_OR_LATER then + return nil, "x509.store:check_revocation: this API is supported from OpenSSL 1.1.0" + end + + if not verified_chain or not chain_lib.istype(verified_chain) then + return nil, "x509.store:check_revocation: expect a x509.chain instance at #1" + end + + local ctx + if OPENSSL_3X then + ctx = C.X509_STORE_CTX_new_ex(ctx_lib.get_libctx(), properties) + else + ctx = C.X509_STORE_CTX_new() + end + if ctx == nil then + return nil, "x509.store:check_revocation: X509_STORE_CTX_new() failed" + end + + ffi_gc(ctx, C.X509_STORE_CTX_free) + + if C.X509_STORE_CTX_init(ctx, self.ctx, nil, nil) ~= 1 then + return nil, format_error("x509.store:check_revocation: X509_STORE_CTX_init") + end + + C.X509_STORE_CTX_set0_verified_chain(ctx, verified_chain.ctx) + + -- enables CRL checking for the certificate chain leaf certificate. + -- An error occurs if a suitable CRL cannot be found. + C.X509_STORE_CTX_set_flags(ctx, flag_crl_check) + + local check_revocation = C.X509_STORE_CTX_get_check_revocation(ctx) + local code = check_revocation(ctx) + if code == 1 then -- succeess + return true, nil + else + local vfy_code = C.X509_STORE_CTX_get_error(ctx) + return nil, ffi_str(C.X509_verify_cert_error_string(vfy_code)) + end +end + return _M diff --git a/src/deps/src/lua-resty-openssl/lua-resty-openssl-0.8.22-1.rockspec b/src/deps/src/lua-resty-openssl/lua-resty-openssl-0.8.23-1.rockspec similarity index 99% rename from src/deps/src/lua-resty-openssl/lua-resty-openssl-0.8.22-1.rockspec rename to src/deps/src/lua-resty-openssl/lua-resty-openssl-0.8.23-1.rockspec index 68dd7dc40..3355766ce 100644 --- a/src/deps/src/lua-resty-openssl/lua-resty-openssl-0.8.22-1.rockspec +++ b/src/deps/src/lua-resty-openssl/lua-resty-openssl-0.8.23-1.rockspec @@ -1,8 +1,8 @@ package = "lua-resty-openssl" -version = "0.8.22-1" +version = "0.8.23-1" source = { url = "git+https://github.com/fffonion/lua-resty-openssl.git", - tag = "0.8.22" + tag = "0.8.23" } description = { detailed = "FFI-based OpenSSL binding for LuaJIT.",