diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc index bceae8b1cfb..c5a29156880 100644 --- a/iocore/net/SSLUtils.cc +++ b/iocore/net/SSLUtils.cc @@ -403,7 +403,7 @@ ssl_verify_client_callback(int preverify_ok, X509_STORE_CTX *ctx) SSLNetVConnection *netvc = SSLNetVCAccess(ssl); netvc->callHooks(TS_EVENT_SSL_VERIFY_CLIENT); - return SSL_TLSEXT_ERR_OK; + return preverify_ok; } // Use the certificate callback for openssl 1.0.2 and greater diff --git a/tests/gold_tests/tls/ssl/server.key b/tests/gold_tests/tls/ssl/server.key index 4c7a661a6bd..9cdfc36aa5f 100644 --- a/tests/gold_tests/tls/ssl/server.key +++ b/tests/gold_tests/tls/ssl/server.key @@ -1,15 +1,28 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDWMHOiUF+ORmZjAxI8MWE9dblb7gQSJ36WCXlPFiFx6ynF+S1E -kXAYpIip5X0pzDUaIbLukxJUAAnOtMEO0PCgxJQUrEtRWh8wiJdbdQJF0Zs/9R+u -SUgb61f+mdTQvhqefBGx+xrpfAcgtcWiZuSA9Q3fvpDj5WOWSPWXBUuxywIDAQAB -AoGBAJPxRX2gjFAGWmQbU/YVmXfNH6navh8X/nx9sLeqrpE0AFeJI/ZPiqDKzMal -B43eSfNxwVi+ZxN0L1ICUbL9KKZvHs/QBxWLA1fGVAXrz7sRplEVvakPpTfHoEnv -sKaMWVKaK/S5WGbDhElb6zb/Lwo19DsIAPjGYqFvzFJBmobJAkEA9iSeTGkR9X26 -GywZoYrIMlRh34htOIRx1UUq88rFzdrCF21kQ4lhBIkX5OZMMy652i2gyak4OZTe -YewIv8jw9QJBAN7EQNHG8jPwXfVp91/fqxVQEfumuP2i6uiWWYQgZCmla2+0xcLZ -pMQ6sQEe10hhTrVnzHgAUVp50Ntn2jwBX78CQF09veGAI9d1Cxzj9cmmAvRd1r2Q -tp8kPOLnUsALXib+6WtqewLCdcf8DtsdClyRJMIraq85tRzK8fryKNZNzkkCQEgA -yS7FDj5JgCU15hZgFk1iPx3HCt44jZM2HaL+UUHAzRQjKxTLAl3G1rWVAWLMyQML -lORoveLvotl4HOruSsMCQQCAx9dV9JUSFoyc1CWILp/FgUH/se4cjQCThGO0DoQQ -vGTYmntY7j9WRJ9esQrjdD6Clw8zM/45GIBNwnXzqo7Z ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCZkEXSlZ+ZFKFg +CPpcDG39e73BuK6E5uE38q2PHh4DV0xcsJnIUx51viqLPwYughxfP0crHyBdXoHV +dW/3WX4gpiGrdiM/dvCouheo0DPaqUUJ2nZKVYh2M57oyeiuJidlKb7BGkfw3HWP +9TV7dVyGWok/cowjopqaLHJWxg/kh2KqvUBD0CHt9Kd1XvgXVmHwE7vCv0j5owv2 +MaExTsFb16uWmVLhl1gNHI2RqCX2yLaebH1DvtbLrit1XErjtaSYeJE9clVRaqT6 +vsvLOhyB5tA9WfZqfBYr/MHDeXQfrbIf+4Cp3aTpq5grc5InIMMH0eOk6/f/4tW+ +nq1lfszZAgMBAAECggEAYvYAqRbXRRVwca0Xel5gO2yU+tSDUw5esWlow8RK3yhR +A6KjV9+Iz6P/UsEIwMwEcLUcrgNfHgybau5Fe4dmqq+lHxQA3xNNP869FIMoB4/x +98mbVYgNau8VRztnAWOBG8ZtMZA4MFZCRMVm8+rL96E8tXCiMwzEyPo/rP/ymfhN +3GRunX+GhfIA79AYNbd7HMVL+cvWWUGUF5Bc5i1wXcLy4I7b9NYtv920BeCLzSFK +BypFB7ku/vKgTcBxe4yxThxPeXPwm4WFzGYKk/Afl1j8tVXCE2U4Y3yykfC0Qk6S +ECZbCKLO2Rxi9fclIDZBHWuKejZhdjHfjeNvZ2vLoQKBgQDJzLmkVLvWAxgl1yvF +U7gwqj/TzYqtVowbjEvTNEnPU1j/hIVI343SVV/EvJmif/iRUop6sRYfLsUjpMsH +CmPysNKL3UtgSYOxLs+0xLhG4OOQRpPSf/uvl9YyWY9G3AqiC7ScthkQjEhZa4c1 +eycYy0jr42kX0OL9MuIH9q0ENQKBgQDCzvGKMs8r5E/Qd3YB9VYB60dx+6G83AHZ +YqIelykObhCdxL9n4K+p4VKKLvgTcCOLYYIkBSWRJWR+ue3s3ey9+XWd2/q4Xvfh +TCjAuO2ibMV+y5ClNlW0fQ/doIVWSDbjO2tZW1jh7YWZ4CtuVrsEisv1sk3KltMB +MguhpTUylQKBgG6TfrncMFzxrx61C+gBmvEXqQffHfkjbnx94OKnSTaQ3jiNHhez +X9v8KhD8o1bWtpay2uyl8pA9qYqBdzqxZ9kJKSW4qd/mCIJjOy87iBpWint5IPD8 +biZmldlbF9ZlJnJq5ZnlclCN/er5r8oPZHoCkj+nieOh8294nUBt25ptAoGAMnPA +EIeaKgbmONpHgLhWPwb9KOL/f1cHT5KA5CVH58nPmdyTqcaCGCAX7Vu+ueIIApgN +SWDf2thxT3S9zuOm5YiO0oRfSZKm5f2AbHE4ciFzgKQd4PvSdH0TN9XT0oW/WVhR +NAI5YcHPIQvyk4/4vXNo4Uf9Z6NqIFwisQmFXoUCgYBK/ZI/HsFsvnR5MV0tFdGM +AdNe6bsQRSZkowoaPxuWbklE4Hn6QvwEmQg3ST2O+vCQV1f1yI6YiWYoptOYscJc +MSs/HxhhaaO5ZsiuPUO6WEPzpNb2CxuIGDDtl83VtUQyjxCmOb6pqqjwzFmZ2bsw +JNMaBCzokrJTxknvauCuSQ== +-----END PRIVATE KEY----- diff --git a/tests/gold_tests/tls/ssl/server.pem b/tests/gold_tests/tls/ssl/server.pem index 58b9b9715b7..2b56cc83ea2 100644 --- a/tests/gold_tests/tls/ssl/server.pem +++ b/tests/gold_tests/tls/ssl/server.pem @@ -1,32 +1,21 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDWMHOiUF+ORmZjAxI8MWE9dblb7gQSJ36WCXlPFiFx6ynF+S1E -kXAYpIip5X0pzDUaIbLukxJUAAnOtMEO0PCgxJQUrEtRWh8wiJdbdQJF0Zs/9R+u -SUgb61f+mdTQvhqefBGx+xrpfAcgtcWiZuSA9Q3fvpDj5WOWSPWXBUuxywIDAQAB -AoGBAJPxRX2gjFAGWmQbU/YVmXfNH6navh8X/nx9sLeqrpE0AFeJI/ZPiqDKzMal -B43eSfNxwVi+ZxN0L1ICUbL9KKZvHs/QBxWLA1fGVAXrz7sRplEVvakPpTfHoEnv -sKaMWVKaK/S5WGbDhElb6zb/Lwo19DsIAPjGYqFvzFJBmobJAkEA9iSeTGkR9X26 -GywZoYrIMlRh34htOIRx1UUq88rFzdrCF21kQ4lhBIkX5OZMMy652i2gyak4OZTe -YewIv8jw9QJBAN7EQNHG8jPwXfVp91/fqxVQEfumuP2i6uiWWYQgZCmla2+0xcLZ -pMQ6sQEe10hhTrVnzHgAUVp50Ntn2jwBX78CQF09veGAI9d1Cxzj9cmmAvRd1r2Q -tp8kPOLnUsALXib+6WtqewLCdcf8DtsdClyRJMIraq85tRzK8fryKNZNzkkCQEgA -yS7FDj5JgCU15hZgFk1iPx3HCt44jZM2HaL+UUHAzRQjKxTLAl3G1rWVAWLMyQML -lORoveLvotl4HOruSsMCQQCAx9dV9JUSFoyc1CWILp/FgUH/se4cjQCThGO0DoQQ -vGTYmntY7j9WRJ9esQrjdD6Clw8zM/45GIBNwnXzqo7Z ------END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIICszCCAhwCCQD4jSkztmlO1TANBgkqhkiG9w0BAQsFADCBnTELMAkGA1UEBhMC -VVMxCzAJBgNVBAgTAklMMRIwEAYDVQQHEwlDaGFtcGFpZ24xDjAMBgNVBAoTBVlh -aG9vMQ0wCwYDVQQLEwRFZGdlMSgwJgYDVQQDEx9qdWljZXByb2R1Y2UuY29ycC5u -ZTEueWFob28uY29tMSQwIgYJKoZIhvcNAQkBFhVwZXJzaWEuYXppekB5YWhvby5j -b20wHhcNMTcwODI4MDM0NDQ1WhcNMjcwODI2MDM0NDQ1WjCBnTELMAkGA1UEBhMC -VVMxCzAJBgNVBAgTAklMMRIwEAYDVQQHEwlDaGFtcGFpZ24xDjAMBgNVBAoTBVlh -aG9vMQ0wCwYDVQQLEwRFZGdlMSgwJgYDVQQDEx9qdWljZXByb2R1Y2UuY29ycC5u -ZTEueWFob28uY29tMSQwIgYJKoZIhvcNAQkBFhVwZXJzaWEuYXppekB5YWhvby5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYwc6JQX45GZmMDEjwxYT11 -uVvuBBInfpYJeU8WIXHrKcX5LUSRcBikiKnlfSnMNRohsu6TElQACc60wQ7Q8KDE -lBSsS1FaHzCIl1t1AkXRmz/1H65JSBvrV/6Z1NC+Gp58EbH7Gul8ByC1xaJm5ID1 -Dd++kOPlY5ZI9ZcFS7HLAgMBAAEwDQYJKoZIhvcNAQELBQADgYEATX7975NdhIbJ -glda+sXI9a86GgOpiuKO+vKubRJQZA+UlPf2vHEONjC2+7Y1aZvZYaKYL74vxGky -zkgp6ANSPl45lqD632x0e1Z7vzW5TkqK1JB2/xH2WgDcQZmP0FuQHzVNs4GjghDr -HCp1+sQDhfPB4aLmLFeyN0TkhdH1N3M= +MIIDZDCCAkygAwIBAgIJANod1+h9CtCaMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNV +BAYTAlVTMQswCQYDVQQIDAJJTDEPMA0GA1UECgwGQXBhY2hlMRowGAYDVQQDDBFy +YW5kb20uc2VydmVyLmNvbTAeFw0xODExMTkxNzEwMTlaFw0yODExMTYxNzEwMTla +MEcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJJTDEPMA0GA1UECgwGQXBhY2hlMRow +GAYDVQQDDBFyYW5kb20uc2VydmVyLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAJmQRdKVn5kUoWAI+lwMbf17vcG4roTm4TfyrY8eHgNXTFywmchT +HnW+Kos/Bi6CHF8/RysfIF1egdV1b/dZfiCmIat2Iz928Ki6F6jQM9qpRQnadkpV +iHYznujJ6K4mJ2UpvsEaR/DcdY/1NXt1XIZaiT9yjCOimposclbGD+SHYqq9QEPQ +Ie30p3Ve+BdWYfATu8K/SPmjC/YxoTFOwVvXq5aZUuGXWA0cjZGoJfbItp5sfUO+ +1suuK3VcSuO1pJh4kT1yVVFqpPq+y8s6HIHm0D1Z9mp8Fiv8wcN5dB+tsh/7gKnd +pOmrmCtzkicgwwfR46Tr9//i1b6erWV+zNkCAwEAAaNTMFEwHQYDVR0OBBYEFI2y +qm0+UAChDAnLrAINeFOuyUlhMB8GA1UdIwQYMBaAFI2yqm0+UAChDAnLrAINeFOu +yUlhMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAA3ZNFbqxcOX +szS5A4EXCepyBJBFejEYy0CsvwQX/ai/pMrw5jqVeF0GAOTpBCVLddyY+ZV1arD2 +Pqi7Qwot9OxEZOzbCBiuMJGotruKgnWFQDHzJ9HA7KDQs270uNESAOG/xW9os9zN +MXApzqfBSR5EIQU5L3RtaiPzoKdQenGQUOj86s0Kon7snDSUzaA2VcfstMWgGvXP +JHtaVusULm0gry32cEap5G5UK+gII6DfLWgFwFGhHHmTz3mKjyGiJQ+09XBtu4lb +ENE+HGRBBA49dUKSr3kwErO4HyHnS0YrsTDnbYURCsGUDma12oijX2sCos6Q4zn8 +3svaouRrucw= -----END CERTIFICATE----- diff --git a/tests/gold_tests/tls/tls_client_verify.test.py b/tests/gold_tests/tls/tls_client_verify.test.py new file mode 100644 index 00000000000..d6298531370 --- /dev/null +++ b/tests/gold_tests/tls/tls_client_verify.test.py @@ -0,0 +1,141 @@ +''' +Test requiring certificate from user agent +''' +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import re + +Test.Summary = ''' +Test various options for requiring certificate from client for mutual authentication TLS +''' + +Test.SkipUnless(Condition.HasProgram("grep", "grep needs to be installed on system for this test to work")) + +ts = Test.MakeATSProcess("ts", select_ports=False) +cafile = "{0}/signer.pem".format(Test.RunDirectory) +cafile2 = "{0}/signer2.pem".format(Test.RunDirectory) +server = Test.MakeOriginServer("server") + +request_header = {"headers": "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""} +response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""} +server.addResponse("sessionlog.json", request_header, response_header) +request_header = {"headers": "GET / HTTP/1.1\r\nHost: bar.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""} +response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""} +server.addResponse("sessionlog.json", request_header, response_header) + +ts.addSSLfile("ssl/server.pem") +ts.addSSLfile("ssl/server.key") +ts.addSSLfile("ssl/signer.pem") + +ts.Variables.ssl_port = 4443 +ts.Disk.records_config.update({ + 'proxy.config.diags.debug.enabled': 1, + 'proxy.config.diags.debug.tags': 'ssl', + 'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir), + 'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir), + 'proxy.config.http.server_ports': '{0}:ssl'.format(ts.Variables.ssl_port), + 'proxy.config.ssl.client.verify.server': 0, + 'proxy.config.ssl.server.cipher_suite': 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:RC4-MD5:AES128-SHA:AES256-SHA:DES-CBC3-SHA!SRP:!DSS:!PSK:!aNULL:!eNULL:!SSLv2', + 'proxy.config.url_remap.pristine_host_hdr' : 1, + 'proxy.config.ssl.client.certification_level': 2, + 'proxy.config.ssl.CA.cert.filename': '{0}/signer.pem'.format(ts.Variables.SSLDir), + 'proxy.config.ssl.TLSv1_3': 0 +}) + +ts.Disk.ssl_multicert_config.AddLine( + 'dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key' +) + +# Just map everything through to origin. This test is concentratign on the user-agent side +ts.Disk.remap_config.AddLine( + 'map / http://127.0.0.1:{0}/'.format(server.Variables.Port) +) + +# Scenario 1: Default no client cert required. cert required for bar.com +ts.Disk.ssl_server_name_yaml.AddLines([ + '- fqdn: bar.com', + ' verify_client: NONE', +]) + +# to foo.com w/o client cert. Should fail +tr = Test.AddTestRun("Connect to foo.com without cert") +tr.Processes.Default.StartBefore(Test.Processes.ts, ready=When.PortOpen(ts.Variables.ssl_port)) +tr.Processes.Default.StartBefore(server) +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'foo.com:{0}:127.0.0.1' https://foo.com:{0}/case1".format(ts.Variables.ssl_port) +tr.Processes.Default.ReturnCode = 35 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ContainsExpression("alert", "TLS handshake should fail") +tr.TimeOut = 5 + +tr = Test.AddTestRun("Connect to foo.com with bad cert") +tr.Setup.Copy("ssl/server.pem") +tr.Setup.Copy("ssl/server.key") +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert server.pem --key server.key --resolve 'foo.com:{0}:127.0.0.1' https://foo.com:{0}/case1".format(ts.Variables.ssl_port) +# Should fail with badly signed certs +tr.Processes.Default.ReturnCode = 35 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ContainsExpression("alert unknown ca", "TLS handshake should fail") +tr.TimeOut = 5 + +tr = Test.AddTestRun("Connect to foo.com with cert") +tr.Setup.Copy("ssl/signed-foo.pem") +tr.Setup.Copy("ssl/signed-foo.key") +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert signed-foo.pem --key signed-foo.key --resolve 'foo.com:{0}:127.0.0.1' https://foo.com:{0}/case1".format(ts.Variables.ssl_port) +tr.Processes.Default.ReturnCode = 0 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") +tr.TimeOut = 5 + +tr = Test.AddTestRun("Connect to bar.com without cert") +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'bar.com:{0}:127.0.0.1' https://bar.com:{0}/case1".format(ts.Variables.ssl_port) +tr.Processes.Default.ReturnCode = 0 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ExcludesExpression("alert", "TLS handshake should succeed") +tr.TimeOut = 5 + +tr = Test.AddTestRun("Connect to bar.com with cert") +tr.Setup.Copy("ssl/signed-bar.pem") +tr.Setup.Copy("ssl/signed-bar.key") +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert signed-bar.pem --key signed-bar.key --resolve 'bar.com:{0}:127.0.0.1' https://bar.com:{0}/case1".format(ts.Variables.ssl_port) +tr.Processes.Default.ReturnCode = 0 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") +tr.TimeOut = 5 + +tr = Test.AddTestRun("Connect to bar.com with bad cert") +tr.Setup.Copy("ssl/server.pem") +tr.Setup.Copy("ssl/server.key") +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert server.pem --key server.key --resolve 'bar.com:{0}:127.0.0.1' https://bar.com:{0}/case1".format(ts.Variables.ssl_port) +# Should fail with badly signed certs +tr.Processes.Default.ReturnCode = 0 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") +tr.TimeOut = 5 + diff --git a/tests/gold_tests/tls/tls_client_verify2.test.py b/tests/gold_tests/tls/tls_client_verify2.test.py new file mode 100644 index 00000000000..8848dc24acd --- /dev/null +++ b/tests/gold_tests/tls/tls_client_verify2.test.py @@ -0,0 +1,129 @@ +''' +Test requiring certificate from user agent +''' +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import re + +Test.Summary = ''' +Test various options for requiring certificate from client for mutual authentication TLS +''' + +Test.SkipUnless(Condition.HasProgram("grep", "grep needs to be installed on system for this test to work")) + +ts = Test.MakeATSProcess("ts", select_ports=False) +cafile = "{0}/signer.pem".format(Test.RunDirectory) +cafile2 = "{0}/signer2.pem".format(Test.RunDirectory) +server = Test.MakeOriginServer("server") + +request_header = {"headers": "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""} +response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""} +server.addResponse("sessionlog.json", request_header, response_header) +request_header = {"headers": "GET / HTTP/1.1\r\nHost: bar.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""} +response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""} +server.addResponse("sessionlog.json", request_header, response_header) + +ts.addSSLfile("ssl/server.pem") +ts.addSSLfile("ssl/server.key") +ts.addSSLfile("ssl/signer.pem") + +ts.Variables.ssl_port = 4443 +ts.Disk.records_config.update({ + 'proxy.config.diags.debug.enabled': 1, + 'proxy.config.diags.debug.tags': 'ssl', + 'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir), + 'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir), + 'proxy.config.http.server_ports': '{0}:ssl'.format(ts.Variables.ssl_port), + 'proxy.config.ssl.client.verify.server': 0, + 'proxy.config.ssl.server.cipher_suite': 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:RC4-MD5:AES128-SHA:AES256-SHA:DES-CBC3-SHA!SRP:!DSS:!PSK:!aNULL:!eNULL:!SSLv2', + 'proxy.config.url_remap.pristine_host_hdr' : 1, + 'proxy.config.ssl.client.certification_level': 0, + 'proxy.config.ssl.CA.cert.path': '', + 'proxy.config.ssl.CA.cert.filename': '{0}/signer.pem'.format(ts.Variables.SSLDir) +}) + +ts.Disk.ssl_multicert_config.AddLine( + 'dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key' +) + +# Just map everything through to origin. This test is concentratign on the user-agent side +ts.Disk.remap_config.AddLine( + 'map / http://127.0.0.1:{0}/'.format(server.Variables.Port) +) + +# Scenario 1: Default no client cert required. cert required for bar.com +ts.Disk.ssl_server_name_yaml.AddLines([ + '- fqdn: bar.com', + ' verify_client: STRICT', +]) + +# to foo.com w/o client cert. Should succeed +tr = Test.AddTestRun("Connect to foo.com without cert") +tr.Processes.Default.StartBefore(Test.Processes.ts, ready=When.PortOpen(ts.Variables.ssl_port)) +tr.Processes.Default.StartBefore(server) +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'foo.com:{0}:127.0.0.1' https://foo.com:{0}/case1".format(ts.Variables.ssl_port) +tr.Processes.Default.ReturnCode = 0 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") +tr.TimeOut = 5 + +tr = Test.AddTestRun("Connect to foo.com with cert") +tr.Setup.Copy("ssl/signed-foo.pem") +tr.Setup.Copy("ssl/signed-foo.key") +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert signed-foo.pem --key signed-foo.key --resolve 'foo.com:{0}:127.0.0.1' https://foo.com:{0}/case1".format(ts.Variables.ssl_port) +tr.Processes.Default.ReturnCode = 0 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") +tr.TimeOut = 5 + +tr = Test.AddTestRun("Connect to bar.com without cert") +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'bar.com:{0}:127.0.0.1' https://bar.com:{0}/case1".format(ts.Variables.ssl_port) +tr.Processes.Default.ReturnCode = 35 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ContainsExpression("alert", "TLS handshake should fail") +tr.TimeOut = 5 + +tr = Test.AddTestRun("Connect to bar.com with cert") +tr.Setup.Copy("ssl/signed-bar.pem") +tr.Setup.Copy("ssl/signed-bar.key") +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert signed-bar.pem --key signed-bar.key --resolve 'bar.com:{0}:127.0.0.1' https://bar.com:{0}/case1".format(ts.Variables.ssl_port) +tr.Processes.Default.ReturnCode = 0 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") +tr.TimeOut = 5 + +tr = Test.AddTestRun("Connect to bar.com with bad cert") +tr.Setup.Copy("ssl/server.pem") +tr.Setup.Copy("ssl/server.key") +tr.StillRunningAfter = ts +tr.StillRunningAfter = server +tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert server.pem --key server.key --resolve 'bar.com:{0}:127.0.0.1' https://bar.com:{0}/case1".format(ts.Variables.ssl_port) +# Should fail with badly signed certs +tr.Processes.Default.ReturnCode = 35 +tr.Processes.Default.TimeOut = 5 +tr.Processes.Default.Streams.All = Testers.ContainsExpression("alert unknown ca", "TLS handshake should fail") +tr.TimeOut = 5 +