aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/cmdline.py6
-rw-r--r--mitmproxy/protocol/tls.py6
-rw-r--r--mitmproxy/proxy/config.py5
-rw-r--r--netlib/tcp.py10
4 files changed, 26 insertions, 1 deletions
diff --git a/mitmproxy/cmdline.py b/mitmproxy/cmdline.py
index b1b860f8..a04a36ba 100644
--- a/mitmproxy/cmdline.py
+++ b/mitmproxy/cmdline.py
@@ -435,6 +435,12 @@ def proxy_ssl_options(parser):
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",
help="Verify upstream server SSL/TLS certificates and fail if invalid "
diff --git a/mitmproxy/protocol/tls.py b/mitmproxy/protocol/tls.py
index 6913396d..22ee8ff9 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 149d4710..9932ec8c 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 6423888a..68a71270 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)