Skip to content

Commit bc289e6

Browse files
committed
fallback to non-mTLS when any cert/key error and log a warning
1 parent aa3c82a commit bc289e6

File tree

1 file changed

+72
-52
lines changed

1 file changed

+72
-52
lines changed

lib/resty/http_connect.lua

Lines changed: 72 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -167,71 +167,91 @@ local function connect(self, options)
167167

168168
local cert_hash
169169
if ssl and ssl_client_cert and ssl_client_priv_key then
170-
local status, res = xpcall(function()
171-
local chain = require("resty.openssl.x509.chain")
172-
local x509 = require("resty.openssl.x509")
173-
local pkey = require("resty.openssl.pkey")
174-
return { chain, x509, pkey }
175-
end, debug.traceback)
176-
177-
if status then
178-
local chain = res[1]
179-
local x509 = res[2]
180-
local pkey = res[3]
181-
182-
if type(ssl_client_cert) ~= "cdata" then
183-
return nil, "bad ssl_client_cert: cdata expected, got " .. type(ssl_client_cert)
170+
-- fallback to non-mTLS when any error
171+
repeat
172+
local cert_type = type(ssl_client_cert)
173+
local key_type = type(ssl_client_priv_key)
174+
175+
if cert_type ~= "cdata" then
176+
ngx_log(ngx_WARN, "bad ssl_client_cert: cdata expected, got " .. cert_type)
177+
break
184178
end
185179

186-
if type(ssl_client_priv_key) ~= "cdata" then
187-
return nil, "bad ssl_client_priv_key: cdata expected, got " .. type(ssl_client_priv_key)
180+
if key_type ~= "cdata" then
181+
ngx_log(ngx_WARN, "bad ssl_client_priv_key: cdata expected, got " .. key_type)
182+
break
188183
end
189184

190-
-- convert from `void*` to `OPENSSL_STACK*`
191-
local cert_chain, err = chain.dup(ffi_cast("OPENSSL_STACK*", ssl_client_cert))
192-
if not cert_chain then
193-
return nil, err
194-
end
195-
196-
if #cert_chain < 1 then
197-
return nil, "no cert in the chain"
198-
end
185+
local status, res = xpcall(function()
186+
local chain = require("resty.openssl.x509.chain")
187+
local x509 = require("resty.openssl.x509")
188+
local pkey = require("resty.openssl.pkey")
189+
return { chain, x509, pkey }
190+
end, debug.traceback)
191+
192+
if status then
193+
local chain = res[1]
194+
local x509 = res[2]
195+
local pkey = res[3]
196+
197+
-- convert from `void*` to `OPENSSL_STACK*`
198+
local cert_chain, err = chain.dup(ffi_cast("OPENSSL_STACK*", ssl_client_cert))
199+
if not cert_chain then
200+
ngx_log(ngx_WARN, "failed to dup the ssl_client_cert, falling back to non-mTLS: " .. err)
201+
break
202+
end
199203

200-
local cert, err = x509.dup(cert_chain[1].ctx)
201-
if not cert then
202-
return nil, err
203-
end
204+
if #cert_chain < 1 then
205+
ngx_log(ngx_WARN, "no cert in ssl_client_cert, falling back to non-mTLS: " .. err)
206+
break
207+
end
204208

205-
-- convert from `void*` to `EVP_PKEY*`
206-
local key, err = pkey.new(ffi_cast("EVP_PKEY*", ssl_client_priv_key))
207-
if not key then
208-
return nil, err
209-
end
210-
-- should not free the cdata passed in
211-
ffi_gc(key.ctx, nil)
209+
local cert, err = x509.dup(cert_chain[1].ctx)
210+
if not cert then
211+
ngx_log(ngx_WARN, "failed to dup the x509, falling back to non-mTLS: " .. err)
212+
break
213+
end
212214

213-
-- check the private key in order to make sure the caller is indeed the holder of the cert
214-
ok, err = cert:check_private_key(key)
215-
if not ok then
216-
return nil, "failed to match the private key with the certificate: " .. err
217-
end
215+
-- convert from `void*` to `EVP_PKEY*`
216+
local key, err = pkey.new(ffi_cast("EVP_PKEY*", ssl_client_priv_key))
217+
if not key then
218+
ngx_log(ngx_WARN, "failed to new the pkey, falling back to non-mTLS: " .. err)
219+
break
220+
end
221+
-- should not free the cdata passed in
222+
ffi_gc(key.ctx, nil)
218223

219-
cert_hash, err = cert:digest("sha256")
220-
if cert_hash then
221-
cert_hash = to_hex(cert_hash) -- convert to hex so that it's printable
224+
-- check the private key in order to make sure the caller is indeed the holder of the cert
225+
ok, err = cert:check_private_key(key)
226+
if not ok then
227+
ngx_log(ngx_WARN, "the private key doesn't match the cert, falling back to non-mTLS: " .. err)
228+
break
229+
end
222230

223-
else
224-
return nil, err
225-
end
231+
cert_hash, err = cert:digest("sha256")
232+
if cert_hash then
233+
cert_hash = to_hex(cert_hash) -- convert to hex so that it's printable
226234

227-
else
228-
if type(res) == "string" and ngx_re_find(res, "module 'resty\\.openssl\\..+' not found") then
229-
ngx_log(ngx_WARN, "can't use mTLS without module `lua-resty-openssl`, falling back to non-mTLS." .. res)
235+
else
236+
ngx_log(ngx_WARN, "failed to calculate the digest of the cert, falling back to non-mTLS: " .. err)
237+
break
238+
end
230239

231240
else
232-
return nil, "failed to load module 'resty.openssl.*':\n" .. res
241+
if type(res) == "string" and ngx_re_find(res, "module 'resty\\.openssl\\..+' not found") then
242+
ngx_log(ngx_WARN, "can't use mTLS without module `lua-resty-openssl`, falling back to non-mTLS:\n "
243+
.. res)
244+
245+
else
246+
ngx_log(ngx_WARN, "failed to load module `resty.openssl.*`, falling back to non-mTLS:\n" .. res)
247+
end
233248
end
234-
end
249+
until true
250+
end
251+
252+
if not cert_hash then
253+
ssl_client_cert = nil
254+
ssl_client_priv_key = nil
235255
end
236256

237257
-- construct a poolname unique within proxy and ssl info

0 commit comments

Comments
 (0)