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

Class ClientHello

mitmproxy/tls.py:14–110  ·  view source on GitHub ↗

A TLS ClientHello is the first message sent by the client when initiating TLS.

Source from the content-addressed store, hash-verified

12
13
14class ClientHello:
15 """
16 A TLS ClientHello is the first message sent by the client when initiating TLS.
17 """
18
19 _raw_bytes: bytes
20
21 def __init__(self, raw_client_hello: bytes, dtls: bool = False):
22 """Create a TLS ClientHello object from raw bytes."""
23 self._raw_bytes = raw_client_hello
24 if dtls:
25 self._client_hello = dtls_client_hello.DtlsClientHello(
26 KaitaiStream(io.BytesIO(raw_client_hello))
27 )
28 else:
29 self._client_hello = tls_client_hello.TlsClientHello(
30 KaitaiStream(io.BytesIO(raw_client_hello))
31 )
32
33 def raw_bytes(self, wrap_in_record: bool = True) -> bytes:
34 """
35 The raw ClientHello bytes as seen on the wire.
36
37 If `wrap_in_record` is True, the ClientHello will be wrapped in a synthetic TLS record
38 (`0x160303 + len(chm) + 0x01 + len(ch)`), which is the format expected by some tools.
39 The synthetic record assumes TLS version (`0x0303`), which may be different from what has been sent over the
40 wire. JA3 hashes are unaffected by this as they only use the TLS version from the ClientHello data structure.
41
42 A future implementation may return not just the exact ClientHello, but also the exact record(s) as seen on the
43 wire.
44 """
45 if isinstance(self._client_hello, dtls_client_hello.DtlsClientHello):
46 raise NotImplementedError
47
48 if wrap_in_record:
49 return (
50 # record layer
51 b"\x16\x03\x03"
52 + (len(self._raw_bytes) + 4).to_bytes(2, byteorder="big")
53 +
54 # handshake header
55 b"\x01"
56 + len(self._raw_bytes).to_bytes(3, byteorder="big")
57 +
58 # ClientHello as defined in https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.2.
59 self._raw_bytes
60 )
61 else:
62 return self._raw_bytes
63
64 @property
65 def cipher_suites(self) -> list[int]:
66 """The cipher suites offered by the client (as raw ints)."""
67 return self._client_hello.cipher_suites.cipher_suites
68
69 @property
70 def sni(self) -> str | None:
71 """

Callers 3

parse_client_helloFunction · 0.90
dtls_parse_client_helloFunction · 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…