MCPcopy Index your code
hub / github.com/mitmproxy/mitmproxy / ClientTLSLayer

Class ClientTLSLayer

mitmproxy/proxy/layers/tls.py:515–681  ·  view source on GitHub ↗

This layer establishes TLS on a single client connection. ┌─────┐ │Start│ └┬────┘ ↓ ┌────────────────────┐ │Wait for ClientHello│ └┬───────────────────┘ ↓ ┌────────────────┐ │Process messages│ └────────────────┘

Source from the content-addressed store, hash-verified

513
514
515class ClientTLSLayer(TLSLayer):
516 """
517 This layer establishes TLS on a single client connection.
518
519 ┌─────┐
520 │Start│
521 └┬────┘
522
523 ┌────────────────────┐
524 │Wait for ClientHello│
525 └┬───────────────────┘
526
527 ┌────────────────┐
528 │Process messages│
529 └────────────────┘
530
531 """
532
533 recv_buffer: bytearray
534 server_tls_available: bool
535 client_hello_parsed: bool = False
536
537 def __init__(self, context: context.Context):
538 if context.client.tls:
539 # In the case of TLS-over-TLS, we already have client TLS. As the outer TLS connection between client
540 # and proxy isn't that interesting to us, we just unset the attributes here and keep the inner TLS
541 # session's attributes.
542 # Alternatively we could create a new Client instance,
543 # but for now we keep it simple. There is a proof-of-concept at
544 # https://github.com/mitmproxy/mitmproxy/commit/9b6e2a716888b7787514733b76a5936afa485352.
545 context.client.alpn = None
546 context.client.cipher = None
547 context.client.sni = None
548 context.client.timestamp_tls_setup = None
549 context.client.tls_version = None
550 context.client.certificate_list = []
551 context.client.mitmcert = None
552 context.client.alpn_offers = []
553 context.client.cipher_list = []
554
555 super().__init__(context, context.client)
556 self.server_tls_available = isinstance(self.context.layers[-2], ServerTLSLayer)
557 self.recv_buffer = bytearray()
558
559 def start_handshake(self) -> layer.CommandGenerator[None]:
560 yield from ()
561
562 def receive_handshake_data(
563 self, data: bytes
564 ) -> layer.CommandGenerator[tuple[bool, str | None]]:
565 if self.client_hello_parsed:
566 return (yield from super().receive_handshake_data(data))
567 self.recv_buffer.extend(data)
568 try:
569 if self.is_dtls:
570 client_hello = dtls_parse_client_hello(self.recv_buffer)
571 else:
572 client_hello = parse_client_hello(self.recv_buffer)

Callers 2

_next_layerMethod · 0.90
_setup_reverse_proxyMethod · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…