class TestHTTPSUpstreamServerVerificationWTrustedCert(tservers.HTTPProxyTest): """ Test upstream server certificate verification with a trusted server cert. """ ssl = True ssloptions = pathod.SSLOptions( cn=b"example.mitmproxy.org", certs=[("example.mitmproxy.org", cdata.path("../data/servercert/trusted-leaf.pem"))]) def _request(self): p = self.pathoc(sni="example.mitmproxy.org") with p.connect(): return p.request("get:/p/242") def test_verification_w_confdir(self, tdata): self.options.update( ssl_insecure=False, ssl_verify_upstream_trusted_confdir=tdata.path( "mitmproxy/data/servercert/"), ssl_verify_upstream_trusted_ca=None, ) assert self._request().status_code == 242 def test_verification_w_pemfile(self, tdata): self.options.update( ssl_insecure=False, ssl_verify_upstream_trusted_confdir=None, ssl_verify_upstream_trusted_ca=tdata.path( "mitmproxy/data/servercert/trusted-root.pem"), ) assert self._request().status_code == 242
class TestHTTPSUpstreamServerVerificationWBadCert(tservers.HTTPProxyTest): """ Test upstream server certificate verification with an untrusted server cert. """ ssl = True ssloptions = pathod.SSLOptions( cn=b"example.mitmproxy.org", certs=[("example.mitmproxy.org", cdata.path("../data/servercert/self-signed.pem"))]) def _request(self): p = self.pathoc(sni="example.mitmproxy.org") with p.connect(): return p.request("get:/p/242") @classmethod def get_options(cls): opts = super().get_options() opts.ssl_verify_upstream_trusted_ca = cdata.path( "../data/servercert/trusted-root.pem") return opts def test_no_verification_w_bad_cert(self): self.options.ssl_insecure = True r = self._request() assert r.status_code == 242 def test_verification_w_bad_cert(self): # We only test for a single invalid cert here. # Actual testing of different root-causes (invalid hostname, expired, ...) # is done in mitmproxy.net. self.options.ssl_insecure = False r = self._request() assert r.status_code == 502 assert b"Certificate verification error" in r.raw_content
class TestHTTPSUpstreamServerVerificationWTrustedCert(tservers.HTTPProxyTest): """ Test upstream server certificate verification with a trusted server cert. """ ssl = True ssloptions = pathod.SSLOptions( cn="trusted-cert", certs=[ ("trusted-cert", tutils.test_data.path("data/trusted-server.crt")) ]) def test_verification_w_cadir(self): self.config.openssl_verification_mode_server = SSL.VERIFY_PEER self.config.openssl_trusted_cadir_server = tutils.test_data.path( "data/trusted-cadir/") self.pathoc() def test_verification_w_pemfile(self): self.config.openssl_verification_mode_server = SSL.VERIFY_PEER self.config.openssl_trusted_ca_server = tutils.test_data.path( "data/trusted-cadir/trusted-ca.pem") self.pathoc()
class TestHTTPS(tservers.HTTPProxyTest, CommonMixin, TcpMixin): ssl = True ssloptions = pathod.SSLOptions(request_client_cert=True) def test_clientcert_file(self, tdata): try: self.options.client_certs = os.path.join( tdata.path("mitmproxy/data/clientcert"), "client.pem") f = self.pathod("304") assert f.status_code == 304 assert self.server.last_log()["request"]["clientcert"]["keyinfo"] finally: self.options.client_certs = None def test_clientcert_dir(self, tdata): try: self.options.client_certs = tdata.path("mitmproxy/data/clientcert") f = self.pathod("304") assert f.status_code == 304 assert self.server.last_log()["request"]["clientcert"]["keyinfo"] finally: self.options.client_certs = None def test_error_post_connect(self): p = self.pathoc() with p.connect(): assert p.request("get:/:i0,'invalid\r\n\r\n'").status_code == 400
class TestHTTPSUpstreamServerVerificationWBadCert(tservers.HTTPProxyTest): """ Test upstream server certificate verification with an untrusted server cert. """ ssl = True ssloptions = pathod.SSLOptions( cn="untrusted-cert", certs=[("untrusted-cert", tutils.test_data.path("data/untrusted-server.crt"))]) def _request(self): p = self.pathoc() # We need to make an actual request because the upstream connection is lazy-loaded. return p.request("get:/p/242") def test_default_verification_w_bad_cert(self): """Should use no verification.""" self.config.openssl_trusted_ca_server = tutils.test_data.path( "data/trusted-cadir/trusted-ca.pem") assert self._request().status_code == 242 def test_no_verification_w_bad_cert(self): self.config.openssl_verification_mode_server = SSL.VERIFY_NONE self.config.openssl_trusted_ca_server = tutils.test_data.path( "data/trusted-cadir/trusted-ca.pem") assert self._request().status_code == 242 def test_verification_w_bad_cert(self): self.config.openssl_verification_mode_server = SSL.VERIFY_PEER self.config.openssl_trusted_ca_server = tutils.test_data.path( "data/trusted-cadir/trusted-ca.pem") assert self._request().status_code == 502
class _TestDaemon: ssloptions = pathod.SSLOptions() @classmethod def setup_class(cls): cls.d = test.Daemon(ssl=cls.ssl, ssloptions=cls.ssloptions, staticdir=tutils.test_data.path("data"), anchors=[(re.compile("/anchor/.*"), "202")]) @classmethod def teardown_class(cls): cls.d.shutdown() def setUp(self): self.d.clear_log() def test_info(self): c = pathoc.Pathoc(("127.0.0.1", self.d.port), ssl=self.ssl, fp=None) c.connect() resp = c.request("get:/api/info") assert tuple(json.loads(resp.content)["version"]) == version.IVERSION def tval(self, requests, showreq=False, showresp=False, explain=False, showssl=False, hexdump=False, timeout=None, ignorecodes=(), ignoretimeout=None, showsummary=True): s = StringIO() c = pathoc.Pathoc(("127.0.0.1", self.d.port), ssl=self.ssl, showreq=showreq, showresp=showresp, explain=explain, hexdump=hexdump, ignorecodes=ignorecodes, ignoretimeout=ignoretimeout, showsummary=showsummary, fp=s) c.connect(showssl=showssl, fp=s) if timeout: c.settimeout(timeout) for i in requests: r = language.parse_pathoc(i).next() if explain: r = r.freeze(language.Settings()) try: c.request(r) except NetlibException: pass return s.getvalue()
class TestHTTPSNoCommonName(tservers.HTTPProxyTest): """ Test what happens if we get a cert without common name back. """ ssl = True ssloptions = pathod.SSLOptions( certs=[("*", cdata.path("../data/no_common_name.pem"))]) def test_http(self): f = self.pathod("202") assert f.sslinfo.certchain[0].get_subject().CN == "127.0.0.1"
class TestHTTPSUpstreamServerVerificationWTrustedCert(tservers.HTTPProxyTest): """ Test upstream server certificate verification with a trusted server cert. """ ssl = True ssloptions = pathod.SSLOptions( cn=b"example.mitmproxy.org", certs=[("example.mitmproxy.org", cdata.path("../data/servercert/trusted-leaf.pem"))]) def _request(self): p = self.pathoc(sni="example.mitmproxy.org") with p.connect(): return p.request("get:/p/242")
def setup_class(cls): opts = cls.ssloptions or {} cls.confdir = tempfile.mkdtemp() opts["confdir"] = cls.confdir so = pathod.SSLOptions(**opts) cls.d = test.Daemon(staticdir=test_data.path("data"), anchors=[(re.compile("/anchor/.*"), "202:da")], ssl=cls.ssl, ssloptions=so, sizelimit=1 * 1024 * 1024, nohang=cls.nohang, timeout=cls.timeout, hexdump=cls.hexdump, nocraft=cls.nocraft, logreq=True, logresp=True, explain=cls.explain)
class TestDaemonSSL(_TestDaemon): ssl = True ssloptions = pathod.SSLOptions( request_client_cert=True, sans=["test1.com", "test2.com"], alpn_select=b'h2', ) def test_sni(self): c = pathoc.Pathoc( ("127.0.0.1", self.d.port), ssl=True, sni="foobar.com", fp=None ) c.connect() c.request("get:/p/200") r = c.request("get:/api/log") d = json.loads(r.content) assert d["log"][0]["request"]["sni"] == "foobar.com" def test_showssl(self): assert "certificate chain" in self.tval(["get:/p/200"], showssl=True) def test_clientcert(self): c = pathoc.Pathoc( ("127.0.0.1", self.d.port), ssl=True, clientcert=tutils.test_data.path("data/clientcert/client.pem"), fp=None ) c.connect() c.request("get:/p/200") r = c.request("get:/api/log") d = json.loads(r.content) assert d["log"][0]["request"]["clientcert"]["keyinfo"] def test_http2_without_ssl(self): fp = cStringIO.StringIO() c = pathoc.Pathoc( ("127.0.0.1", self.d.port), use_http2=True, ssl=False, fp = fp ) tutils.raises(NotImplementedError, c.connect)
class AddUpstreamCertsToClientChainMixin: ssl = True servercert = tutils.test_data.path("data/trusted-server.crt") ssloptions = pathod.SSLOptions(cn="trusted-cert", certs=[("trusted-cert", servercert)]) def test_add_upstream_certs_to_client_chain(self): with open(self.servercert, "rb") as f: d = f.read() upstreamCert = SSLCert.from_pem(d) p = self.pathoc() upstream_cert_found_in_client_chain = False for receivedCert in p.server_certs: if receivedCert.digest('sha256') == upstreamCert.digest('sha256'): upstream_cert_found_in_client_chain = True break assert (upstream_cert_found_in_client_chain == self.add_upstream_certs_to_client_chain)
class AddUpstreamCertsToClientChainMixin: ssl = True servercert = cdata.path("../data/servercert/trusted-root.pem") ssloptions = pathod.SSLOptions(cn=b"example.mitmproxy.org", certs=[("example.mitmproxy.org", servercert) ]) def test_add_upstream_certs_to_client_chain(self): with open(self.servercert, "rb") as f: d = f.read() upstreamCert = certs.Cert.from_pem(d) p = self.pathoc() with p.connect(): upstream_cert_found_in_client_chain = False for receivedCert in p.server_certs: if receivedCert.digest('sha256') == upstreamCert.digest( 'sha256'): upstream_cert_found_in_client_chain = True break assert (upstream_cert_found_in_client_chain == self.master.options.add_upstream_certs_to_client_chain)