def create_client_proxy_ssl_conn(self, tls_start: tls.TlsStartData) -> None: client: context.Client = tls_start.context.client server: context.Server = tls_start.context.server cert, key, chain_file = self.get_cert(tls_start.context) if not client.cipher_list and ctx.options.ciphers_client: client.cipher_list = ctx.options.ciphers_client.split(":") # don't assign to client.cipher_list, doesn't need to be stored. cipher_list = client.cipher_list or DEFAULT_CIPHERS ssl_ctx = net_tls.create_client_proxy_context( min_version=net_tls.Version[ctx.options.tls_version_client_min], max_version=net_tls.Version[ctx.options.tls_version_client_max], cipher_list=cipher_list, cert=cert, key=key, chain_file=chain_file, request_client_cert=False, alpn_select_callback=alpn_select_callback, extra_chain_certs=server.certificate_list, dhparams=self.certstore.dhparams, ) tls_start.ssl_conn = SSL.Connection(ssl_ctx) tls_start.ssl_conn.set_app_data(AppData( server_alpn=server.alpn, http2=ctx.options.http2, )) tls_start.ssl_conn.set_accept_state()
def test_sslkeylogfile(tdata, monkeypatch): keylog = [] monkeypatch.setattr(tls, "log_master_secret", lambda conn, secrets: keylog.append(secrets)) store = certs.CertStore.from_files( Path( tdata.path( "mitmproxy/net/data/verificationcerts/trusted-root.pem")), Path(tdata.path("mitmproxy/net/data/dhparam.pem"))) entry = store.get_cert("example.com", [], None) cctx = tls.create_proxy_server_context( min_version=tls.DEFAULT_MIN_VERSION, max_version=tls.DEFAULT_MAX_VERSION, cipher_list=None, verify=tls.Verify.VERIFY_NONE, hostname=None, ca_path=None, ca_pemfile=None, client_cert=None, alpn_protos=(), ) sctx = tls.create_client_proxy_context( min_version=tls.DEFAULT_MIN_VERSION, max_version=tls.DEFAULT_MAX_VERSION, cipher_list=None, cert=entry.cert, key=entry.privatekey, chain_file=entry.chain_file, alpn_select_callback=None, request_client_cert=False, extra_chain_certs=(), dhparams=store.dhparams, ) server = SSL.Connection(sctx) server.set_accept_state() client = SSL.Connection(cctx) client.set_connect_state() read, write = client, server while True: try: print(read) read.do_handshake() except SSL.WantReadError: write.bio_write(read.bio_read(2**16)) else: break read, write = write, read assert keylog assert keylog[0].startswith(b"SERVER_HANDSHAKE_TRAFFIC_SECRET")
def tls_start_client(self, tls_start: tls.TlsData) -> None: """Establish TLS between client and proxy.""" if tls_start.ssl_conn is not None: return # a user addon has already provided the pyOpenSSL context. client: connection.Client = tls_start.context.client server: connection.Server = tls_start.context.server entry = self.get_cert(tls_start.context) if not client.cipher_list and ctx.options.ciphers_client: client.cipher_list = ctx.options.ciphers_client.split(":") # don't assign to client.cipher_list, doesn't need to be stored. cipher_list = client.cipher_list or DEFAULT_CIPHERS if ctx.options.add_upstream_certs_to_client_chain: # pragma: no cover # exempted from coverage until https://bugs.python.org/issue18233 is fixed. extra_chain_certs = server.certificate_list else: extra_chain_certs = [] ssl_ctx = net_tls.create_client_proxy_context( min_version=net_tls.Version[ctx.options.tls_version_client_min], max_version=net_tls.Version[ctx.options.tls_version_client_max], cipher_list=tuple(cipher_list), cert=entry.cert, key=entry.privatekey, chain_file=entry.chain_file, request_client_cert=False, alpn_select_callback=alpn_select_callback, extra_chain_certs=tuple(extra_chain_certs), dhparams=self.certstore.dhparams, ) tls_start.ssl_conn = SSL.Connection(ssl_ctx) # Force HTTP/1 for secure web proxies, we currently don't support CONNECT over HTTP/2. # There is a proof-of-concept branch at https://github.com/mhils/mitmproxy/tree/http2-proxy, # but the complexity outweighs the benefits for now. if len(tls_start.context.layers) == 2 and isinstance( tls_start.context.layers[0], modes.HttpProxy): client_alpn: Optional[bytes] = b"http/1.1" else: client_alpn = client.alpn tls_start.ssl_conn.set_app_data( AppData( client_alpn=client_alpn, server_alpn=server.alpn, http2=ctx.options.http2, )) tls_start.ssl_conn.set_accept_state()
def create_client_proxy_ssl_conn(self, tls_start: tls.TlsStartData) -> None: client: connection.Client = tls_start.context.client server: connection.Server = tls_start.context.server entry = self.get_cert(tls_start.context) if not client.cipher_list and ctx.options.ciphers_client: client.cipher_list = ctx.options.ciphers_client.split(":") # don't assign to client.cipher_list, doesn't need to be stored. cipher_list = client.cipher_list or DEFAULT_CIPHERS if ctx.options.add_upstream_certs_to_client_chain: # pragma: no cover # exempted from coverage until https://bugs.python.org/issue18233 is fixed. extra_chain_certs = server.certificate_list else: extra_chain_certs = [] ssl_ctx = net_tls.create_client_proxy_context( min_version=net_tls.Version[ctx.options.tls_version_client_min], max_version=net_tls.Version[ctx.options.tls_version_client_max], cipher_list=cipher_list, cert=entry.cert, key=entry.privatekey, chain_file=entry.chain_file, request_client_cert=False, alpn_select_callback=alpn_select_callback, extra_chain_certs=extra_chain_certs, dhparams=self.certstore.dhparams, ) tls_start.ssl_conn = SSL.Connection(ssl_ctx) tls_start.ssl_conn.set_app_data( AppData( client_alpn=client.alpn, server_alpn=server.alpn, http2=ctx.options.http2, )) tls_start.ssl_conn.set_accept_state()