lua-nginx-module icon indicating copy to clipboard operation
lua-nginx-module copied to clipboard

ssl.verify_client uses only first certificate in chain to perform validation

Open mlga opened this issue 3 years ago • 1 comments

Problem

When I define multiple CA certificates:

-----BEGIN CERTIFICATE-----
<CA cert one>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<CA cert two>
-----END CERTIFICATE-----

parse them using ssl.parse_pem_cert, and pass the resulting cert chain to ssl.verify_client, only the first certificate is being used to perform client validation.

When I change the order of certificates, again only the first one is being used. Always only requests with certs signed by first CA are being verified successfully.

Verification error is

Certificate signature failure

Code snippet

init_by_lua_block

(not exact code, some of it is extracted to separate module, loaded by require)

local ssl = require "ngx.ssl"
local ca = {}

local cert_data = [[-----BEGIN CERTIFICATE-----
<CA cert one>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<CA cert two>
-----END CERTIFICATE-----]]

local cert_chain, err = ssl.parse_pem_cert(cert_data)
if err ~= nil then
    ngx.log(ngx.ERR, "Cert chain parsing error. ", err)
end

ca.cert_chain = cert_chain

return ca

ssl_certificate_by_lua_block

local ssl = require "ngx.ssl"
local ca = require "custom.ca"

ssl.verify_client(ca.cert_chain, 1) -- was playing with different depths as well

access_by_lua_file

Here, I just check value of ngx.var.ssl_client_verify and return error / proceed.

Software versions

I'm using openresty docker image.

Software Version
Nginx openresty/1.19.9.1
ngx_lua 0.10.20

Full info:

$ nginx -V
nginx version: openresty/1.19.9.1
built by gcc 10.2.1 20200804 (Red Hat 10.2.1-2) (GCC)
built with OpenSSL 1.1.1k  25 Mar 2021 (running with OpenSSL 1.1.1n  15 Mar 2022)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --with-cc-opt='-O2 -DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/zlib/include -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl111/include' --add-module=../ngx_devel_kit-0.3.1 --add-module=../echo-nginx-module-0.62 --add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2 --add-module=../set-misc-nginx-module-0.32 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.08 --add-module=../srcache-nginx-module-0.32 --add-module=../ngx_lua-0.10.20 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.19 --add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-module-0.3.7 --add-module=../ngx_stream_lua-0.0.10 --with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -L/usr/local/openresty/zlib/lib -L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl111/lib -Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl111/lib' --with-cc='ccache gcc -fdiagnostics-color=always' --with-pcre-jit --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_v2_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_auth_request_module --with-http_secure_link_module --with-http_random_index_module --with-http_gzip_static_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-threads --with-compat --with-stream --with-http_ssl_module

Am I doing something wrong or unexpected? Is there any way to perform client auth against multiple CAs? I can prepare small docker-compose.yml with a demonstration of required.

mlga avatar May 13 '22 12:05 mlga

Can you provide a reproducible test case so we can analyze the problem more quickly?

zhuizhuhaomeng avatar May 30 '22 02:05 zhuizhuhaomeng