From 0169271bf993aa16b4d5627eda8523552661d7ef Mon Sep 17 00:00:00 2001 From: ikoz Date: Wed, 2 Mar 2016 15:23:33 +0000 Subject: [PATCH 1/9] New option: Add server certs to client chain If enabled, append all server certificates to the certificate chain served to the client, as extras. Can be used to bypass certain certificate pinning impementations. --- mitmproxy/cmdline.py | 6 ++++++ mitmproxy/protocol/tls.py | 6 ++++++ mitmproxy/proxy/config.py | 5 ++++- netlib/tcp.py | 10 ++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/mitmproxy/cmdline.py b/mitmproxy/cmdline.py index b1b860f83..a04a36ba7 100644 --- a/mitmproxy/cmdline.py +++ b/mitmproxy/cmdline.py @@ -434,6 +434,12 @@ def proxy_ssl_options(parser): action="store_true", dest="no_upstream_cert", help="Don't connect to upstream server to look up certificate details." ) + group.add_argument( + "--add-server-certs-to-client-chain", default=False, + action="store_true", dest="add_server_certs_to_client_chain", + help="Add all the certificates of the server to the certificate chain " + "that will be served to the client, as extras." + ) group.add_argument( "--verify-upstream-cert", default=False, action="store_true", dest="ssl_verify_upstream_cert", diff --git a/mitmproxy/protocol/tls.py b/mitmproxy/protocol/tls.py index 6913396d5..22ee8ff98 100644 --- a/mitmproxy/protocol/tls.py +++ b/mitmproxy/protocol/tls.py @@ -432,6 +432,11 @@ class TlsLayer(Layer): self.log("Establish TLS with client", "debug") cert, key, chain_file = self._find_cert() + if self.config.add_server_certs_to_client_chain: + extra_certs = self.server_conn.server_certs + else: + extra_certs = None + try: self.client_conn.convert_to_ssl( cert, key, @@ -441,6 +446,7 @@ class TlsLayer(Layer): dhparams=self.config.certstore.dhparams, chain_file=chain_file, alpn_select_callback=self.__alpn_select_callback, + extra_chain_certs = extra_certs, ) # Some TLS clients will not fail the handshake, # but will immediately throw an "unexpected eof" error on the first read. diff --git a/mitmproxy/proxy/config.py b/mitmproxy/proxy/config.py index 149d47105..9932ec8c0 100644 --- a/mitmproxy/proxy/config.py +++ b/mitmproxy/proxy/config.py @@ -67,6 +67,7 @@ class ProxyConfig: ssl_verify_upstream_cert=False, ssl_verify_upstream_trusted_cadir=None, ssl_verify_upstream_trusted_ca=None, + add_server_certs_to_client_chain=False, ): self.host = host self.port = port @@ -107,6 +108,7 @@ class ProxyConfig: self.openssl_verification_mode_server = SSL.VERIFY_NONE self.openssl_trusted_cadir_server = ssl_verify_upstream_trusted_cadir self.openssl_trusted_ca_server = ssl_verify_upstream_trusted_ca + self.add_server_certs_to_client_chain = add_server_certs_to_client_chain def process_proxy_options(parser, options): @@ -206,5 +208,6 @@ def process_proxy_options(parser, options): ssl_version_server=options.ssl_version_server, ssl_verify_upstream_cert=options.ssl_verify_upstream_cert, ssl_verify_upstream_trusted_cadir=options.ssl_verify_upstream_trusted_cadir, - ssl_verify_upstream_trusted_ca=options.ssl_verify_upstream_trusted_ca + ssl_verify_upstream_trusted_ca=options.ssl_verify_upstream_trusted_ca, + add_server_certs_to_client_chain=options.add_server_certs_to_client_chain, ) diff --git a/netlib/tcp.py b/netlib/tcp.py index 6423888a1..68a712702 100644 --- a/netlib/tcp.py +++ b/netlib/tcp.py @@ -584,6 +584,7 @@ class TCPClient(_Connection): self.address = address self.source_address = source_address self.cert = None + self.server_certs = [] self.ssl_verification_error = None self.sni = None @@ -668,6 +669,10 @@ class TCPClient(_Connection): self.cert = certutils.SSLCert(self.connection.get_peer_certificate()) + # Keep all server certificates in a list + for i in self.connection.get_peer_cert_chain(): + self.server_certs.append(certutils.SSLCert(i)) + # Validate TLS Hostname try: crt = dict( @@ -734,6 +739,7 @@ class BaseHandler(_Connection): request_client_cert=None, chain_file=None, dhparams=None, + extra_chain_certs=None, **sslctx_kwargs): """ cert: A certutils.SSLCert object or the path to a certificate @@ -769,6 +775,10 @@ class BaseHandler(_Connection): else: context.use_certificate_chain_file(cert) + if extra_chain_certs: + for i in extra_chain_certs: + context.add_extra_chain_cert(i.x509) + if handle_sni: # SNI callback happens during do_handshake() context.set_tlsext_servername_callback(handle_sni) From 9b970b0303d0cc0f7106da63108ab86dd05656bf Mon Sep 17 00:00:00 2001 From: ikoz Date: Tue, 15 Mar 2016 14:40:54 +0000 Subject: [PATCH 2/9] fix for sslinfo cert chain printing bug - now all certs get printed --- pathod/pathoc.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pathod/pathoc.py b/pathod/pathoc.py index c0a33b628..64a81c945 100644 --- a/pathod/pathoc.py +++ b/pathod/pathoc.py @@ -42,7 +42,8 @@ class SSLInfo(object): "Cipher: %s, %s bit, %s" % self.cipher, "SSL certificate chain:" ] - for i in self.certchain: + for n,i in enumerate(self.certchain): + parts.append(" Certificate [%s]" % n) parts.append("\tSubject: ") for cn in i.get_subject().get_components(): parts.append("\t\t%s=%s" % cn) @@ -69,7 +70,7 @@ class SSLInfo(object): s = certutils.SSLCert(i) if s.altnames: parts.append("\tSANs: %s" % " ".join(s.altnames)) - return "\n".join(parts) + return "\n".join(parts) From 776e625413fe7937853e1c812773f123b0bad9fc Mon Sep 17 00:00:00 2001 From: ikoz Date: Tue, 15 Mar 2016 14:58:38 +0000 Subject: [PATCH 3/9] Add tests for add-server-certs-to-client-chain feature --- test/mitmproxy/test_server.py | 60 +++++++++++++++++++++++++++++++++++ test/mitmproxy/tservers.py | 2 ++ 2 files changed, 62 insertions(+) diff --git a/test/mitmproxy/test_server.py b/test/mitmproxy/test_server.py index d7b23bbb8..3286df892 100644 --- a/test/mitmproxy/test_server.py +++ b/test/mitmproxy/test_server.py @@ -999,3 +999,63 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxyTest): # (both terminated) # nothing happened here assert self.chain[1].tmaster.state.flow_count() == 2 + + +class TestHTTPSAddServerCertsToClientChainTrue(tservers.HTTPProxyTest): + ssl = True + add_server_certs_to_client_chain = True + servercert = tutils.test_data.path("data/trusted-server.crt") + ssloptions = pathod.SSLOptions( + cn="trusted-cert", + certs=[ + ("trusted-cert", servercert) + ] + ) + + def test_add_server_certs_to_client_chain_true(self): + """ + If --add-server-certs-to-client-chain is True, then the client should receive the server's certificates + """ + with open(self.servercert, "rb") as f: + d = f.read() + c1 = SSLCert.from_pem(d) + p = self.pathoc() + print("digest of p.cert[1]: %s"%p.server_certs[1].digest('sha256')) + print("digest of c1.cert[1]: %s"%c1.digest('sha256')) + server_cert_found_in_client_chain = False + + for cert in p.server_certs: + if cert.digest('sha256') == c1.digest('sha256'): + server_cert_found_in_client_chain = True + break + + assert(server_cert_found_in_client_chain == True) + + +class TestHTTPSAddServerCertsToClientChainFalse(tservers.HTTPProxyTest): + ssl = True + add_server_certs_to_client_chain = False + servercert = tutils.test_data.path("data/trusted-server.crt") + ssloptions = pathod.SSLOptions( + cn="trusted-cert", + certs=[ + ("trusted-cert", servercert) + ] + ) + + def test_add_server_certs_to_client_chain_false(self): + """ + If --add-server-certs-to-client-chain is False, then the client should not receive the server's certificates + """ + with open(self.servercert, "rb") as f: + d = f.read() + c1 = SSLCert.from_pem(d) + p = self.pathoc() + server_cert_found_in_client_chain = False + + for cert in p.server_certs: + if cert.digest('sha256') == c1.digest('sha256'): + server_cert_found_in_client_chain = True + break + + assert(server_cert_found_in_client_chain == False) diff --git a/test/mitmproxy/tservers.py b/test/mitmproxy/tservers.py index b7b5de9e8..cabd8e1f9 100644 --- a/test/mitmproxy/tservers.py +++ b/test/mitmproxy/tservers.py @@ -86,6 +86,7 @@ class ProxyTestBase(object): no_upstream_cert = False authenticator = None masterclass = TestMaster + add_server_certs_to_client_chain = False @classmethod def setup_class(cls): @@ -129,6 +130,7 @@ class ProxyTestBase(object): no_upstream_cert = cls.no_upstream_cert, cadir = cls.cadir, authenticator = cls.authenticator, + add_server_certs_to_client_chain = cls.add_server_certs_to_client_chain, ) From efc3e942d5444dc345ae3f65d1e08f9a3b6313b1 Mon Sep 17 00:00:00 2001 From: ikoz Date: Wed, 16 Mar 2016 17:43:48 +0000 Subject: [PATCH 4/9] Restructuring of the AddServerCertsToClientChain test so that it uses a Mixin - also removed some extra printf statements --- test/mitmproxy/test_server.py | 87 +++++++++++++++-------------------- 1 file changed, 37 insertions(+), 50 deletions(-) diff --git a/test/mitmproxy/test_server.py b/test/mitmproxy/test_server.py index 3286df892..560c7b34b 100644 --- a/test/mitmproxy/test_server.py +++ b/test/mitmproxy/test_server.py @@ -1001,61 +1001,48 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxyTest): assert self.chain[1].tmaster.state.flow_count() == 2 -class TestHTTPSAddServerCertsToClientChainTrue(tservers.HTTPProxyTest): - ssl = True +class AddServerCertsToClientChainMixin: + + def test_add_server_certs_to_client_chain(self): + with open(self.servercert, "rb") as f: + d = f.read() + c1 = SSLCert.from_pem(d) + p = self.pathoc() + server_cert_found_in_client_chain = False + for cert in p.server_certs: + if cert.digest('sha256') == c1.digest('sha256'): + server_cert_found_in_client_chain = True + break + assert(server_cert_found_in_client_chain == self.add_server_certs_to_client_chain) + + +class TestHTTPSAddServerCertsToClientChainTrue(tservers.HTTPProxyTest, AddServerCertsToClientChainMixin): + + """ + If --add-server-certs-to-client-chain is True, then the client should receive the server's certificates + """ add_server_certs_to_client_chain = True - servercert = tutils.test_data.path("data/trusted-server.crt") - ssloptions = pathod.SSLOptions( - cn="trusted-cert", - certs=[ - ("trusted-cert", servercert) - ] - ) - - def test_add_server_certs_to_client_chain_true(self): - """ - If --add-server-certs-to-client-chain is True, then the client should receive the server's certificates - """ - with open(self.servercert, "rb") as f: - d = f.read() - c1 = SSLCert.from_pem(d) - p = self.pathoc() - print("digest of p.cert[1]: %s"%p.server_certs[1].digest('sha256')) - print("digest of c1.cert[1]: %s"%c1.digest('sha256')) - server_cert_found_in_client_chain = False - - for cert in p.server_certs: - if cert.digest('sha256') == c1.digest('sha256'): - server_cert_found_in_client_chain = True - break - - assert(server_cert_found_in_client_chain == True) - - -class TestHTTPSAddServerCertsToClientChainFalse(tservers.HTTPProxyTest): ssl = True - add_server_certs_to_client_chain = False servercert = tutils.test_data.path("data/trusted-server.crt") ssloptions = pathod.SSLOptions( - cn="trusted-cert", - certs=[ - ("trusted-cert", servercert) - ] + cn="trusted-cert", + certs=[ + ("trusted-cert", servercert) + ] ) - def test_add_server_certs_to_client_chain_false(self): - """ - If --add-server-certs-to-client-chain is False, then the client should not receive the server's certificates - """ - with open(self.servercert, "rb") as f: - d = f.read() - c1 = SSLCert.from_pem(d) - p = self.pathoc() - server_cert_found_in_client_chain = False - for cert in p.server_certs: - if cert.digest('sha256') == c1.digest('sha256'): - server_cert_found_in_client_chain = True - break +class TestHTTPSAddServerCertsToClientChainFalse(tservers.HTTPProxyTest, AddServerCertsToClientChainMixin): - assert(server_cert_found_in_client_chain == False) + """ + If --add-server-certs-to-client-chain is False, then the client should not receive the server's certificates + """ + add_server_certs_to_client_chain = False + ssl = True + servercert = tutils.test_data.path("data/trusted-server.crt") + ssloptions = pathod.SSLOptions( + cn="trusted-cert", + certs=[ + ("trusted-cert", servercert) + ] + ) From d26c7f4ca58165377f60d68babd47cf7e9377b3e Mon Sep 17 00:00:00 2001 From: ikoz Date: Wed, 16 Mar 2016 18:43:51 +0000 Subject: [PATCH 5/9] Move more init things inside AddServerCertsToClientChainMixin --- test/mitmproxy/test_server.py | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/test/mitmproxy/test_server.py b/test/mitmproxy/test_server.py index 560c7b34b..a2d1a5789 100644 --- a/test/mitmproxy/test_server.py +++ b/test/mitmproxy/test_server.py @@ -1003,6 +1003,15 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxyTest): class AddServerCertsToClientChainMixin: + ssl = True + servercert = tutils.test_data.path("data/trusted-server.crt") + ssloptions = pathod.SSLOptions( + cn="trusted-cert", + certs=[ + ("trusted-cert", servercert) + ] + ) + def test_add_server_certs_to_client_chain(self): with open(self.servercert, "rb") as f: d = f.read() @@ -1016,33 +1025,17 @@ class AddServerCertsToClientChainMixin: assert(server_cert_found_in_client_chain == self.add_server_certs_to_client_chain) -class TestHTTPSAddServerCertsToClientChainTrue(tservers.HTTPProxyTest, AddServerCertsToClientChainMixin): +class TestHTTPSAddServerCertsToClientChainTrue(AddServerCertsToClientChainMixin, tservers.HTTPProxyTest): """ - If --add-server-certs-to-client-chain is True, then the client should receive the server's certificates + If --add-server-certs-to-client-chain is True, then the client should receive the upstream server's certificates """ add_server_certs_to_client_chain = True - ssl = True - servercert = tutils.test_data.path("data/trusted-server.crt") - ssloptions = pathod.SSLOptions( - cn="trusted-cert", - certs=[ - ("trusted-cert", servercert) - ] - ) -class TestHTTPSAddServerCertsToClientChainFalse(tservers.HTTPProxyTest, AddServerCertsToClientChainMixin): +class TestHTTPSAddServerCertsToClientChainFalse(AddServerCertsToClientChainMixin, tservers.HTTPProxyTest): """ - If --add-server-certs-to-client-chain is False, then the client should not receive the server's certificates + If --add-server-certs-to-client-chain is False, then the client should not receive the upstream server's certificates """ add_server_certs_to_client_chain = False - ssl = True - servercert = tutils.test_data.path("data/trusted-server.crt") - ssloptions = pathod.SSLOptions( - cn="trusted-cert", - certs=[ - ("trusted-cert", servercert) - ] - ) From 02e378486b9daa7159503a4bdcd7bed9d85e119e Mon Sep 17 00:00:00 2001 From: ikoz Date: Wed, 16 Mar 2016 19:15:44 +0000 Subject: [PATCH 6/9] Create mutually exclusive group for add-server-certs-to-client-chain and verify-upstream-cert command line options. These are not meaningful together. --- mitmproxy/cmdline.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mitmproxy/cmdline.py b/mitmproxy/cmdline.py index a04a36ba7..2184ce948 100644 --- a/mitmproxy/cmdline.py +++ b/mitmproxy/cmdline.py @@ -434,13 +434,14 @@ def proxy_ssl_options(parser): action="store_true", dest="no_upstream_cert", help="Don't connect to upstream server to look up certificate details." ) - group.add_argument( + subgroup = group.add_mutually_exclusive_group() + subgroup.add_argument( "--add-server-certs-to-client-chain", default=False, action="store_true", dest="add_server_certs_to_client_chain", help="Add all the certificates of the server to the certificate chain " "that will be served to the client, as extras." ) - group.add_argument( + subgroup.add_argument( "--verify-upstream-cert", default=False, action="store_true", dest="ssl_verify_upstream_cert", help="Verify upstream server SSL/TLS certificates and fail if invalid " From 9cc55f211fcc74990eb5fafc3945dec6599f94b7 Mon Sep 17 00:00:00 2001 From: ikoz Date: Wed, 16 Mar 2016 19:20:18 +0000 Subject: [PATCH 7/9] Rename 'server' to 'upstream' in identifiers related to the AddServerCertsToClientChain feature --- mitmproxy/cmdline.py | 8 ++++---- mitmproxy/protocol/tls.py | 2 +- mitmproxy/proxy/config.py | 6 +++--- test/mitmproxy/test_server.py | 24 ++++++++++++------------ test/mitmproxy/tservers.py | 4 ++-- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/mitmproxy/cmdline.py b/mitmproxy/cmdline.py index 2184ce948..7b9f2b82f 100644 --- a/mitmproxy/cmdline.py +++ b/mitmproxy/cmdline.py @@ -436,10 +436,10 @@ def proxy_ssl_options(parser): ) subgroup = group.add_mutually_exclusive_group() subgroup.add_argument( - "--add-server-certs-to-client-chain", default=False, - action="store_true", dest="add_server_certs_to_client_chain", - help="Add all the certificates of the server to the certificate chain " - "that will be served to the client, as extras." + "--add-upstream-certs-to-client-chain", default=False, + action="store_true", dest="add_upstream_certs_to_client_chain", + help="Add all certificates of the upstream server to the certificate chain " + "that will be served to the proxy client, as extras." ) subgroup.add_argument( "--verify-upstream-cert", default=False, diff --git a/mitmproxy/protocol/tls.py b/mitmproxy/protocol/tls.py index 22ee8ff98..7a4d53fe0 100644 --- a/mitmproxy/protocol/tls.py +++ b/mitmproxy/protocol/tls.py @@ -432,7 +432,7 @@ class TlsLayer(Layer): self.log("Establish TLS with client", "debug") cert, key, chain_file = self._find_cert() - if self.config.add_server_certs_to_client_chain: + if self.config.add_upstream_certs_to_client_chain: extra_certs = self.server_conn.server_certs else: extra_certs = None diff --git a/mitmproxy/proxy/config.py b/mitmproxy/proxy/config.py index 9932ec8c0..311d25993 100644 --- a/mitmproxy/proxy/config.py +++ b/mitmproxy/proxy/config.py @@ -67,7 +67,7 @@ class ProxyConfig: ssl_verify_upstream_cert=False, ssl_verify_upstream_trusted_cadir=None, ssl_verify_upstream_trusted_ca=None, - add_server_certs_to_client_chain=False, + add_upstream_certs_to_client_chain=False, ): self.host = host self.port = port @@ -108,7 +108,7 @@ class ProxyConfig: self.openssl_verification_mode_server = SSL.VERIFY_NONE self.openssl_trusted_cadir_server = ssl_verify_upstream_trusted_cadir self.openssl_trusted_ca_server = ssl_verify_upstream_trusted_ca - self.add_server_certs_to_client_chain = add_server_certs_to_client_chain + self.add_upstream_certs_to_client_chain = add_upstream_certs_to_client_chain def process_proxy_options(parser, options): @@ -209,5 +209,5 @@ def process_proxy_options(parser, options): ssl_verify_upstream_cert=options.ssl_verify_upstream_cert, ssl_verify_upstream_trusted_cadir=options.ssl_verify_upstream_trusted_cadir, ssl_verify_upstream_trusted_ca=options.ssl_verify_upstream_trusted_ca, - add_server_certs_to_client_chain=options.add_server_certs_to_client_chain, + add_upstream_certs_to_client_chain=options.add_upstream_certs_to_client_chain, ) diff --git a/test/mitmproxy/test_server.py b/test/mitmproxy/test_server.py index a2d1a5789..26e53e8ae 100644 --- a/test/mitmproxy/test_server.py +++ b/test/mitmproxy/test_server.py @@ -1001,7 +1001,7 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxyTest): assert self.chain[1].tmaster.state.flow_count() == 2 -class AddServerCertsToClientChainMixin: +class AddUpstreamCertsToClientChainMixin: ssl = True servercert = tutils.test_data.path("data/trusted-server.crt") @@ -1012,30 +1012,30 @@ class AddServerCertsToClientChainMixin: ] ) - def test_add_server_certs_to_client_chain(self): + def test_add_upstream_certs_to_client_chain(self): with open(self.servercert, "rb") as f: d = f.read() - c1 = SSLCert.from_pem(d) + upstreamCert = SSLCert.from_pem(d) p = self.pathoc() - server_cert_found_in_client_chain = False - for cert in p.server_certs: - if cert.digest('sha256') == c1.digest('sha256'): - server_cert_found_in_client_chain = True + 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(server_cert_found_in_client_chain == self.add_server_certs_to_client_chain) + assert(upstream_cert_found_in_client_chain == self.add_upstream_certs_to_client_chain) -class TestHTTPSAddServerCertsToClientChainTrue(AddServerCertsToClientChainMixin, tservers.HTTPProxyTest): +class TestHTTPSAddUpstreamCertsToClientChainTrue(AddUpstreamCertsToClientChainMixin, tservers.HTTPProxyTest): """ If --add-server-certs-to-client-chain is True, then the client should receive the upstream server's certificates """ - add_server_certs_to_client_chain = True + add_upstream_certs_to_client_chain = True -class TestHTTPSAddServerCertsToClientChainFalse(AddServerCertsToClientChainMixin, tservers.HTTPProxyTest): +class TestHTTPSAddUpstreamCertsToClientChainFalse(AddUpstreamCertsToClientChainMixin, tservers.HTTPProxyTest): """ If --add-server-certs-to-client-chain is False, then the client should not receive the upstream server's certificates """ - add_server_certs_to_client_chain = False + add_upstream_certs_to_client_chain = False diff --git a/test/mitmproxy/tservers.py b/test/mitmproxy/tservers.py index cabd8e1f9..4fa519cc6 100644 --- a/test/mitmproxy/tservers.py +++ b/test/mitmproxy/tservers.py @@ -86,7 +86,7 @@ class ProxyTestBase(object): no_upstream_cert = False authenticator = None masterclass = TestMaster - add_server_certs_to_client_chain = False + add_upstream_certs_to_client_chain = False @classmethod def setup_class(cls): @@ -130,7 +130,7 @@ class ProxyTestBase(object): no_upstream_cert = cls.no_upstream_cert, cadir = cls.cadir, authenticator = cls.authenticator, - add_server_certs_to_client_chain = cls.add_server_certs_to_client_chain, + add_upstream_certs_to_client_chain = cls.add_upstream_certs_to_client_chain, ) From 8ed491201a8ec56585b0e35d9c17e18231b174f8 Mon Sep 17 00:00:00 2001 From: ikoz Date: Wed, 16 Mar 2016 22:45:27 +0000 Subject: [PATCH 8/9] Revert "Create mutually exclusive group for add-server-certs-to-client-chain and verify-upstream-cert command line options. These are not meaningful together." This reverts commit 02e378486b9daa7159503a4bdcd7bed9d85e119e. --- mitmproxy/cmdline.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mitmproxy/cmdline.py b/mitmproxy/cmdline.py index 7b9f2b82f..d7de350ff 100644 --- a/mitmproxy/cmdline.py +++ b/mitmproxy/cmdline.py @@ -434,14 +434,13 @@ def proxy_ssl_options(parser): action="store_true", dest="no_upstream_cert", help="Don't connect to upstream server to look up certificate details." ) - subgroup = group.add_mutually_exclusive_group() - subgroup.add_argument( + group.add_argument( "--add-upstream-certs-to-client-chain", default=False, action="store_true", dest="add_upstream_certs_to_client_chain", help="Add all certificates of the upstream server to the certificate chain " "that will be served to the proxy client, as extras." ) - subgroup.add_argument( + group.add_argument( "--verify-upstream-cert", default=False, action="store_true", dest="ssl_verify_upstream_cert", help="Verify upstream server SSL/TLS certificates and fail if invalid " From b4e7aaf2f68af60ec32219d27d3d10b79f5d0610 Mon Sep 17 00:00:00 2001 From: ikoz Date: Wed, 16 Mar 2016 22:57:57 +0000 Subject: [PATCH 9/9] Make the add-server-certs-to-client-chain and verify-upstream-cert options mutually exclusive whily processing the proxy options. Do the same for the add-server-certs-to-client-chain and no-upstream-cert options. --- mitmproxy/proxy/config.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/mitmproxy/proxy/config.py b/mitmproxy/proxy/config.py index 311d25993..bd02c628c 100644 --- a/mitmproxy/proxy/config.py +++ b/mitmproxy/proxy/config.py @@ -138,14 +138,26 @@ def process_proxy_options(parser, options): "Transparent, SOCKS5, reverse and upstream proxy mode " "are mutually exclusive. Read the docs on proxy modes to understand why." ) - + if options.add_upstream_certs_to_client_chain and options.no_upstream_cert: + return parser.error( + "The no-upstream-cert and add-upstream-certs-to-client-chain " + "options are mutually exclusive. If no-upstream-cert is enabled " + "then the upstream certificate is not retrieved before generating " + "the client certificate chain." + ) + if options.add_upstream_certs_to_client_chain and options.ssl_verify_upstream_cert: + return parser.error( + "The verify-upstream-cert and add-upstream-certs-to-client-chain " + "options are mutually exclusive. If upstream certificates are verified " + "then extra upstream certificates are not available for inclusion " + "to the client chain." + ) if options.clientcerts: options.clientcerts = os.path.expanduser(options.clientcerts) if not os.path.exists(options.clientcerts): return parser.error( - "Client certificate path does not exist: %s" % options.clientcerts + "Client certificate path does not exist: %s" % options.clientcerts ) - if options.auth_nonanonymous or options.auth_singleuser or options.auth_htpasswd: if options.transparent_proxy: