1''' 2Test requiring certificate from user agent 3''' 4# Licensed to the Apache Software Foundation (ASF) under one 5# or more contributor license agreements. See the NOTICE file 6# distributed with this work for additional information 7# regarding copyright ownership. The ASF licenses this file 8# to you under the Apache License, Version 2.0 (the 9# "License"); you may not use this file except in compliance 10# with the License. You may obtain a copy of the License at 11# 12# http://www.apache.org/licenses/LICENSE-2.0 13# 14# Unless required by applicable law or agreed to in writing, software 15# distributed under the License is distributed on an "AS IS" BASIS, 16# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17# See the License for the specific language governing permissions and 18# limitations under the License. 19 20 21Test.Summary = ''' 22Test various options for requiring certificate from client for mutual authentication TLS 23''' 24 25ts = Test.MakeATSProcess("ts", command="traffic_manager", select_ports=True, enable_tls=True) 26cafile = "{0}/signer.pem".format(Test.RunDirectory) 27cafile2 = "{0}/signer2.pem".format(Test.RunDirectory) 28server = Test.MakeOriginServer("server") 29server2 = Test.MakeOriginServer("server2") 30 31request_header = {"headers": "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""} 32response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""} 33server.addResponse("sessionlog.json", request_header, response_header) 34request_header = {"headers": "GET / HTTP/1.1\r\nHost: bar.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""} 35response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""} 36server.addResponse("sessionlog.json", request_header, response_header) 37 38ts.addSSLfile("ssl/server.pem") 39ts.addSSLfile("ssl/server.key") 40ts.addSSLfile("ssl/signer.pem") 41 42ts.Disk.records_config.update({ 43 'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir), 44 'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir), 45 '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', 46 'proxy.config.url_remap.pristine_host_hdr': 1, 47 'proxy.config.ssl.client.certification_level': 2, 48 'proxy.config.ssl.CA.cert.filename': '{0}/signer.pem'.format(ts.Variables.SSLDir), 49 'proxy.config.exec_thread.autoconfig.scale': 1.0, 50 'proxy.config.ssl.TLSv1_3': 0 51}) 52 53ts.Disk.ssl_multicert_config.AddLine( 54 'dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key' 55) 56 57# Just map everything through to origin. This test is concentratign on the user-agent side 58ts.Disk.remap_config.AddLine( 59 'map / http://127.0.0.1:{0}/'.format(server.Variables.Port) 60) 61 62# Scenario 1: Default no client cert required. cert required for bar.com 63ts.Disk.sni_yaml.AddLines([ 64 'sni:', 65 '- fqdn: bob.bar.com', 66 ' verify_client: NONE', 67 '- fqdn: "bob.com"', 68 ' verify_client: STRICT', 69 '- fqdn: bob.*.com', 70 ' verify_client: NONE', 71 '- fqdn: "*bar.com"', 72 ' verify_client: STRICT', 73]) 74 75ts.Disk.logging_yaml.AddLines( 76 ''' 77logging: 78 formats: 79 - name: testformat 80 format: '%<pssc> %<cquc> %<pscert> %<cscert>' 81 logs: 82 - mode: ascii 83 format: testformat 84 filename: squid 85'''.split("\n") 86) 87 88# to foo.com w/o client cert. Should fail 89tr = Test.AddTestRun("Connect to foo.com without cert") 90tr.Processes.Default.StartBefore(Test.Processes.ts) 91tr.Processes.Default.StartBefore(server) 92tr.StillRunningAfter = ts 93tr.StillRunningAfter = server 94tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'foo.com:{0}:127.0.0.1' https://foo.com:{0}/case1".format( 95 ts.Variables.ssl_port) 96tr.Processes.Default.ReturnCode = 35 97 98tr = Test.AddTestRun("Connect to foo.com with bad cert") 99tr.Setup.Copy("ssl/server.pem") 100tr.Setup.Copy("ssl/server.key") 101tr.StillRunningAfter = ts 102tr.StillRunningAfter = server 103tr.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}/case2".format( 104 ts.Variables.ssl_port) 105# Should fail with badly signed certs 106tr.Processes.Default.ReturnCode = 35 107 108tr = Test.AddTestRun("Connect to foo.com with cert") 109tr.Setup.Copy("ssl/signed-foo.pem") 110tr.Setup.Copy("ssl/signed-foo.key") 111tr.StillRunningAfter = ts 112tr.StillRunningAfter = server 113tr.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}/case3".format( 114 ts.Variables.ssl_port) 115tr.Processes.Default.ReturnCode = 0 116tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") 117 118tr = Test.AddTestRun("Connect to bob.bar.com without cert") 119tr.StillRunningAfter = ts 120tr.StillRunningAfter = server 121tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'bob.bar.com:{0}:127.0.0.1' https://bob.bar.com:{0}/case4".format( 122 ts.Variables.ssl_port) 123tr.Processes.Default.ReturnCode = 0 124tr.Processes.Default.Streams.All = Testers.ExcludesExpression("alert", "TLS handshake should succeed") 125 126tr = Test.AddTestRun("Connect to bob.bar.com with cert") 127tr.Setup.Copy("ssl/signed-bob-bar.pem") 128tr.Setup.Copy("ssl/signed-bar.key") 129tr.StillRunningAfter = ts 130tr.StillRunningAfter = server 131tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert ./signed-bob-bar.pem --key ./signed-bar.key --resolve 'bob.bar.com:{0}:127.0.0.1' https://bob.bar.com:{0}/case5".format( 132 ts.Variables.ssl_port) 133tr.Processes.Default.ReturnCode = 0 134tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") 135 136tr = Test.AddTestRun("Connect to bob.bar.com with bad cert") 137tr.Setup.Copy("ssl/server.pem") 138tr.Setup.Copy("ssl/server.key") 139tr.StillRunningAfter = ts 140tr.StillRunningAfter = server 141tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert ./server.pem --key ./server.key --resolve 'bob.bar.com:{0}:127.0.0.1' https://bob.bar.com:{0}/case6".format( 142 ts.Variables.ssl_port) 143tr.Processes.Default.ReturnCode = 0 144tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") 145 146tr = Test.AddTestRun("Connect to bob.foo.com without cert") 147tr.StillRunningAfter = ts 148tr.StillRunningAfter = server 149tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'bob.foo.com:{0}:127.0.0.1' https://bob.foo.com:{0}/case7".format( 150 ts.Variables.ssl_port) 151tr.Processes.Default.ReturnCode = 0 152tr.Processes.Default.Streams.All = Testers.ExcludesExpression("alert", "TLS handshake should succeed") 153 154tr = Test.AddTestRun("Connect to bob.foo.com with cert") 155tr.Setup.Copy("ssl/signed-bob-foo.pem") 156tr.Setup.Copy("ssl/signed-foo.key") 157tr.StillRunningAfter = ts 158tr.StillRunningAfter = server 159tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert ./signed-bob-foo.pem --key ./signed-foo.key --resolve 'bob.foo.com:{0}:127.0.0.1' https://bob.foo.com:{0}/case8".format( 160 ts.Variables.ssl_port) 161tr.Processes.Default.ReturnCode = 0 162tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") 163 164tr = Test.AddTestRun("Connect to bob.foo.com with bad cert") 165tr.Setup.Copy("ssl/server.pem") 166tr.Setup.Copy("ssl/server.key") 167tr.StillRunningAfter = ts 168tr.StillRunningAfter = server 169tr.Processes.Default.Command = "curl --tls-max 1.2 -k --cert ./server.pem --key ./server.key --resolve 'bob.foo.com:{0}:127.0.0.1' https://bob.foo.com:{0}/case9".format( 170 ts.Variables.ssl_port) 171tr.Processes.Default.ReturnCode = 0 172tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "Check response") 173 174tr = Test.AddTestRun("Connect to bar.com without cert") 175tr.StillRunningAfter = ts 176tr.StillRunningAfter = server 177tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'bar.com:{0}:127.0.0.1' https://bar.com:{0}/case10".format( 178 ts.Variables.ssl_port) 179tr.Processes.Default.ReturnCode = 35 180 181tr = Test.AddTestRun("Connect to bar.com with cert") 182tr.Setup.Copy("ssl/signed-bar.pem") 183tr.Setup.Copy("ssl/signed-bar.key") 184tr.StillRunningAfter = ts 185tr.StillRunningAfter = server 186tr.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}/case11".format( 187 ts.Variables.ssl_port) 188tr.Processes.Default.ReturnCode = 0 189tr.Processes.Default.Streams.All = Testers.ExcludesExpression("error", "TLS handshake should succeed") 190 191tr = Test.AddTestRun("Connect to bar.com with bad cert") 192tr.Setup.Copy("ssl/server.pem") 193tr.Setup.Copy("ssl/server.key") 194tr.StillRunningAfter = ts 195tr.StillRunningAfter = server 196tr.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}/case12".format( 197 ts.Variables.ssl_port) 198tr.Processes.Default.ReturnCode = 35 199 200 201# Test that the fqdn's match completely. bob.com should require client certificate. bob.com.com should not 202tr = Test.AddTestRun("Connect to bob.com without cert, should fail") 203tr.StillRunningAfter = ts 204tr.StillRunningAfter = server 205tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'bob.com:{0}:127.0.0.1' https://bob.com:{0}/case13".format( 206 ts.Variables.ssl_port) 207tr.Processes.Default.ReturnCode = 35 208 209tr = Test.AddTestRun("Connect to bob.com.com without cert, should succeed") 210tr.StillRunningAfter = ts 211tr.StillRunningAfter = server 212tr.Processes.Default.Command = "curl --tls-max 1.2 -k --resolve 'bob.com.com:{0}:127.0.0.1' https://bob.com.com:{0}/case14".format( 213 ts.Variables.ssl_port) 214tr.Processes.Default.ReturnCode = 0 215 216tr = Test.AddTestRun("Wait for the access log to write out") 217tr.Processes.Default.StartBefore(server2, ready=When.FileExists(ts.Disk.squid_log)) 218tr.StillRunningAfter = ts 219tr.StillRunningAfter = server 220tr.StillRunningAfter = server2 221tr.Processes.Default.Command = 'echo "Log file exists"' 222tr.Processes.Default.ReturnCode = 0 223 224ts.Disk.squid_log.Content = "gold/clientcert-accesslog.gold" 225