diff --git a/src/ssl/ngx_lua_kong_ssl.c b/src/ssl/ngx_lua_kong_ssl.c index a16f7872..a9d3e295 100644 --- a/src/ssl/ngx_lua_kong_ssl.c +++ b/src/ssl/ngx_lua_kong_ssl.c @@ -251,6 +251,13 @@ ngx_lua_kong_ssl_set_upstream_ssl(ngx_lua_kong_ssl_ctx_t *ctx, ngx_connection_t goto failed; } + /* clear the old chain */ + if (SSL_clear_chain_certs(sc) == 0) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, + "SSL_clear_chain_certs() failed"); + goto failed; + } + /* read rest of the chain */ for (i = 1; i < sk_X509_num(chain); i++) { diff --git a/t/002-upstream-tls.t b/t/002-upstream-tls.t index c975b924..4ccea4b1 100644 --- a/t/002-upstream-tls.t +++ b/t/002-upstream-tls.t @@ -5,7 +5,7 @@ use Cwd qw(cwd); repeat_each(2); -plan tests => repeat_each() * (blocks() * 6); +plan tests => repeat_each() * (blocks() * 6 + 1); my $pwd = cwd(); @@ -810,3 +810,81 @@ X509_check_host(): match [error] [crit] [alert] + + + +=== TEST 14: set_upstream_client_cert_and_key should clear the old chain +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name example.com; + ssl_certificate ../../cert/example.com.crt; + ssl_certificate_key ../../cert/example.com.key; + ssl_client_certificate ../../cert/ca.crt; + ssl_verify_client on; + + server_tokens off; + + location /foo { + default_type 'text/plain'; + more_clear_headers Date; + echo 'it works!'; + } + } + + upstream foo { + server unix:$TEST_NGINX_HTML_DIR/nginx.sock; + + balancer_by_lua_block { + collectgarbage() -- to make leak check mode pass + + local tls = require("resty.kong.tls") + local ssl = require("ngx.ssl") + + local f = assert(io.open("t/cert/client_leaf.crt")) + local cert_data = f:read("*a") + f:close() + + local chain = assert(ssl.parse_pem_cert(cert_data)) + + f = assert(io.open("t/cert/client_example.com.key")) + local key_data = f:read("*a") + f:close() + + local key = assert(ssl.parse_pem_priv_key(key_data)) + + local ok, err = tls.set_upstream_cert_and_key(chain, key) + if not ok then + ngx.say("set_upstream_cert_and_key failed: ", err) + end + } + } +--- config + server_tokens off; + + location /t { + proxy_ssl_trusted_certificate ../../cert/ca.crt; + proxy_ssl_verify on; + proxy_ssl_name example.com; + proxy_ssl_certificate ../../cert/client_example.com.crt; + proxy_ssl_certificate_key ../../cert/client_example.com.key; + proxy_ssl_session_reuse off; + proxy_pass https://foo/foo; + } + +--- request +GET /t +--- response_body_like +.+400 The SSL certificate error.+ + +--- error_log +verify:0, error:21, depth:0, subject:"/C=US/ST=California/O=Kong Testing/CN=foo@example.com", issuer:"/C=US/ST=California/O=Kong Testing/CN=Kong Testing Intermidiate CA" +client SSL certificate verify error: (21:unable to verify the first certificate) while reading client request headers + +--- error_code: 400 +--- no_error_log +[error] +[crit] +[alert] diff --git a/t/cert/client_leaf.crt b/t/cert/client_leaf.crt new file mode 100644 index 00000000..6fafa161 --- /dev/null +++ b/t/cert/client_leaf.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFIjCCAwqgAwIBAgICIAEwDQYJKoZIhvcNAQELBQAwYDELMAkGA1UEBhMCVVMx +EzARBgNVBAgMCkNhbGlmb3JuaWExFTATBgNVBAoMDEtvbmcgVGVzdGluZzElMCMG +A1UEAwwcS29uZyBUZXN0aW5nIEludGVybWlkaWF0ZSBDQTAeFw0xOTA1MDIyMDAz +MTFaFw0yOTA0MjgyMDAzMTFaMFMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp +Zm9ybmlhMRUwEwYDVQQKDAxLb25nIFRlc3RpbmcxGDAWBgNVBAMMD2Zvb0BleGFt +cGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJldMxsZHDxA +RpbSXdIFZiTf8D0dYgsPnsmx5tVjA/zrVBSVBPO9KunaXNm4Z6JWmUwenzFGbzWP +NLfbLn4khuoczzqSru5XfbyH1HrD0cd5lkf44Dw1/otfIFDBleiR/OWEiAxwS4zi +xIajNyvLr3gC5dv+F+JuWpW1yVQxybIDQWoI25xpd3+ZkXO+OLkToo+YpuwIDlUj +6Rkm5kbqoxDpaDihA2bsAqjNG7G+SHthaNyACsQsU/t6BHSWzHumScN0CxJ+TeVH +fTZklelItZ6YP0B0RQjzvSGA423UgALzqJglGPe8UDjm3BMlg2xhTfnfy1J6Vmbt +5jx6FOXUARsCAwEAAaOB8jCB7zAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIF +oDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgQ2xpZW50IENlcnRp +ZmljYXRlMB0GA1UdDgQWBBRTzNOmhGRXaZamxVfnlKXarIOEmDAfBgNVHSMEGDAW +gBQLDgQOl/htYk8k8DvGb9IKO40RETAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYw +FAYIKwYBBQUHAwIGCCsGAQUFBwMEMCsGA1UdEQQkMCKBD2Zvb0BleGFtcGxlLmNv +bYEPYmFyQGV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQBziDuVjU0I1CwO +b1Cx2TJpzi3l5FD/ozrMZT6F3EpkJFGZWgXrsXHz/0qKTrsbB2m3/fcyd0lwQ5Lh +fz8X1HPrwXa3BqZskNu1vOUNiqAYWvQ5gtbpweJ96LzMSYVGLK78NigYTtK+Rgq3 +As5CVfLXDBburrQNGyRTsilCQDNBvIpib0eqg/HJCNDFMPrBzTMPpUutyatfpFH2 +UwTiVBfA14YYDxZaetYWeksy28XH6Uj0ylyz67VHND+gBMmQNLXQHJTIDh8JuIf2 +ec6o4HrtyyuRE3urNQmcPMAokacm4NKw2+og6Rg1VS/pckaSPOlSEmNnKFiXStv+ +AVd77NGriUWDFCmnrFNOPOIS019W0oOk6YMwTUDSa86Ii6skCtBLHmp/cingkTWg +7KEbdT1uVVPgseC2AFpQ1BWJOjjtyW3GWuxERIhuab9/ckTz6BuIiuK7mfsvPBrn +BqjZyt9WAx8uaWMS/ZrmIj3fUXefaPtl27jMSsiU5oi2vzFu0xiXJb6Jr7RQxD3O +XRnycL/chWnp7eVV1TQS+XzZ3ZZQIjckDWX4E+zGo4o9pD1YC0eytbIlSuqYVr/t +dZmD2gqju3Io9EXPDlRDP2VIX9q1euF9caz1vpLCfV+F8wVPtZe5p6JbNugdgjix +nDZ2sD2xGXy6/fNG75oHveYo6MREFw== +-----END CERTIFICATE-----