Skip to content

Commit 290cb84

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

File tree

1 file changed

+71
-51
lines changed

1 file changed

+71
-51
lines changed

lib/resty/http_connect.lua

Lines changed: 71 additions & 51 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
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)
195191

196-
if #cert_chain < 1 then
197-
return nil, "no cert in the chain"
198-
end
192+
if status then
193+
local chain = res[1]
194+
local x509 = res[2]
195+
local pkey = res[3]
199196

200-
local cert, err = x509.dup(cert_chain[1].ctx)
201-
if not cert then
202-
return nil, err
203-
end
204197

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)
198+
-- convert from `void*` to `OPENSSL_STACK*`
199+
local cert_chain, err = chain.dup(ffi_cast("OPENSSL_STACK*", ssl_client_cert))
200+
if not cert_chain then
201+
ngx_log(ngx_WARN, "failed to dup the ssl_client_cert, falling back to non-mTLS: " .. err)
202+
break
203+
end
212204

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
205+
if #cert_chain < 1 then
206+
ngx_log(ngx_WARN, "no cert in ssl_client_cert, falling back to non-mTLS: " .. err)
207+
break
208+
end
218209

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
210+
local cert, err = x509.dup(cert_chain[1].ctx)
211+
if not cert then
212+
ngx_log(ngx_WARN, "failed to dup the x509, falling back to non-mTLS: " .. err)
213+
break
214+
end
222215

223-
else
224-
return nil, err
225-
end
216+
-- convert from `void*` to `EVP_PKEY*`
217+
local key, err = pkey.new(ffi_cast("EVP_PKEY*", ssl_client_priv_key))
218+
if not key then
219+
ngx_log(ngx_WARN, "failed to new the pkey, falling back to non-mTLS: " .. err)
220+
break
221+
end
222+
-- should not free the cdata passed in
223+
ffi_gc(key.ctx, nil)
226224

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)
225+
-- check the private key in order to make sure the caller is indeed the holder of the cert
226+
ok, err = cert:check_private_key(key)
227+
if not ok then
228+
ngx_log(ngx_WARN, "the private key doesn't match the cert, falling back to non-mTLS: " .. err)
229+
break
230+
end
231+
232+
cert_hash, err = cert:digest("sha256")
233+
if cert_hash then
234+
cert_hash = to_hex(cert_hash) -- convert to hex so that it's printable
235+
236+
else
237+
ngx_log(ngx_WARN, "failed to calculate the digest of the cert, falling back to non-mTLS: " .. err)
238+
break
239+
end
230240

231241
else
232-
return nil, "failed to load module 'resty.openssl.*':\n" .. res
242+
if type(res) == "string" and ngx_re_find(res, "module 'resty\\.openssl\\..+' not found") then
243+
ngx_log(ngx_WARN, "can't use mTLS without module `lua-resty-openssl`, falling back to non-mTLS:\n " .. 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)