@@ -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