@@ -167,71 +167,91 @@ local function connect(self, options)
167
167
168
168
local cert_hash
169
169
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
184
178
end
185
179
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
188
183
end
189
184
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 )
195
191
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 ]
199
196
200
- local cert , err = x509 .dup (cert_chain [1 ].ctx )
201
- if not cert then
202
- return nil , err
203
- end
204
197
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
212
204
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
218
209
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
222
215
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 )
226
224
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
230
240
231
241
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
233
248
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
235
255
end
236
256
237
257
-- construct a poolname unique within proxy and ssl info
0 commit comments