ssl2 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ssl2-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,180 @@
1
+ Metadata-Version: 2.3
2
+ Name: ssl2
3
+ Version: 1.0.0
4
+ Summary: PEP 748 TLS interface: typed ClientHello model and parser, JA3, JA4 and Akamai fingerprints, proxies, sockets and asyncio streams
5
+ Requires-Python: >=3.14.8
6
+ Project-URL: Repository, https://github.com/baobien-dev/ssl2
7
+ Description-Content-Type: text/markdown
8
+
9
+ # ssl2
10
+
11
+ TLS interface for Python 3.14 after PEP 748, plus what a real client needs around it: typed IANA registries, a ClientHello model with a builder and a wire parser, JA3, JA4 and Akamai fingerprints, proxies, a blocking socket and an asyncio stream that run on any PEP 748 `TLSBuffer`, a session cache and the system trust store. Pure Python, no dependencies. The engine is a separate package, for example `boring-ssl2`.
12
+
13
+ ```text
14
+ uv add ssl2
15
+ ```
16
+
17
+ ## ClientHello model and fingerprints
18
+
19
+ ```python
20
+ from ssl2 import (
21
+ JA3,
22
+ JA4,
23
+ CertificateCompressionAlgorithm,
24
+ CipherSuite,
25
+ ClientHelloBuilder,
26
+ ECPointFormat,
27
+ ExtensionType,
28
+ NamedGroup,
29
+ NextProtocol,
30
+ ProtocolVersion,
31
+ PskKeyExchangeMode,
32
+ SignatureScheme,
33
+ )
34
+
35
+ chrome = (
36
+ ClientHelloBuilder()
37
+ .supported_versions(ProtocolVersion.TLS_1_3, ProtocolVersion.TLS_1_2)
38
+ .cipher_suites(
39
+ CipherSuite.TLS_AES_128_GCM_SHA256,
40
+ CipherSuite.TLS_AES_256_GCM_SHA384,
41
+ CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
42
+ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
43
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
44
+ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
45
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
46
+ CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
47
+ CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
48
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
49
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
50
+ CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
51
+ CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384,
52
+ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
53
+ CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
54
+ )
55
+ .extensions(
56
+ ExtensionType.server_name,
57
+ ExtensionType.extended_main_secret,
58
+ ExtensionType.renegotiation_info,
59
+ ExtensionType.supported_groups,
60
+ ExtensionType.ec_point_formats,
61
+ ExtensionType.session_ticket,
62
+ ExtensionType.application_layer_protocol_negotiation,
63
+ ExtensionType.status_request,
64
+ ExtensionType.signature_algorithms,
65
+ ExtensionType.signed_certificate_timestamp,
66
+ ExtensionType.key_share,
67
+ ExtensionType.psk_key_exchange_modes,
68
+ ExtensionType.supported_versions,
69
+ ExtensionType.compress_certificate,
70
+ ExtensionType.application_settings_old,
71
+ ExtensionType.encrypted_client_hello,
72
+ )
73
+ .supported_groups(NamedGroup.X25519MLKEM768, NamedGroup.x25519, NamedGroup.secp256r1, NamedGroup.secp384r1)
74
+ .key_shares(NamedGroup.X25519MLKEM768, NamedGroup.x25519)
75
+ .ec_point_formats(ECPointFormat.uncompressed)
76
+ .signature_algorithms(
77
+ SignatureScheme.ecdsa_secp256r1_sha256,
78
+ SignatureScheme.rsa_pss_rsae_sha256,
79
+ SignatureScheme.rsa_pkcs1_sha256,
80
+ SignatureScheme.ecdsa_secp384r1_sha384,
81
+ SignatureScheme.rsa_pss_rsae_sha384,
82
+ SignatureScheme.rsa_pkcs1_sha384,
83
+ SignatureScheme.rsa_pss_rsae_sha512,
84
+ SignatureScheme.rsa_pkcs1_sha512,
85
+ )
86
+ .application_protocols(NextProtocol.H2, NextProtocol.HTTP1)
87
+ .application_settings(NextProtocol.H2)
88
+ .certificate_compression(CertificateCompressionAlgorithm.brotli)
89
+ .psk_key_exchange_modes(PskKeyExchangeMode.psk_dhe_ke)
90
+ .grease()
91
+ .build()
92
+ )
93
+ print(JA4.of(chrome).text) # t13d1516h2_8daaf6152771_02713d6af862
94
+ print(JA3.of(chrome).digest) # 5549240a5133e94d2053bfbc454228ef
95
+ ```
96
+
97
+ Every setter also takes the code point itself, so `.extensions(0, 23, 65281)` and `.cipher_suites(0x1301)` mean the same thing; that is how a captured fingerprint arrives. Unassigned and GREASE code points still parse:
98
+
99
+ ```python
100
+ from ssl2 import CipherSuite, ExtensionType
101
+
102
+ print(ExtensionType(17613).name, CipherSuite(0x1A1A).name, CipherSuite(0x1A1A).is_grease) # application_settings unassigned_0x1a1a True
103
+ ```
104
+
105
+ The parser reads a ClientHello from the TLS record or the bare handshake message, strips GREASE and sets `grease`:
106
+
107
+ ```python
108
+ from ssl2 import ClientHelloParser
109
+
110
+ hello = ClientHelloParser.parse(client_hello_bytes)
111
+ print(hello.grease, hello.cipher_suites, hello.key_share_groups)
112
+ ```
113
+
114
+ Fingerprint text forms parse back, except the hashed JA4 form:
115
+
116
+ ```python
117
+ from ssl2 import JA4, AkamaiFingerprint
118
+
119
+ ja4 = JA4.of(chrome)
120
+ print(ja4.raw) # t13d1516h2_002f,0035,...,cca9_0005,000a,...,ff01_0403,0804,...
121
+ print(JA4.parse(ja4.raw).text == ja4.text, JA4.parse(ja4.original).text == ja4.text) # True True
122
+ akamai = AkamaiFingerprint.parse("1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p")
123
+ print(akamai.digest) # 52d84b11737d980aef856699f885ca86
124
+ print(JA3.parse(JA3.of(chrome).text) == JA3.of(chrome)) # True
125
+ ```
126
+
127
+ `JA3.builder()` starts a `ClientHelloBuilder` from the JA3 fields; the payloads JA3 does not carry, such as signature schemes, key shares and ALPN, go in before `build()`.
128
+
129
+ ## Configuration, credentials, trust
130
+
131
+ ```python
132
+ from ssl2 import Certificate, PrivateKey, SigningChain, TLSClientConfiguration, TLSServerConfiguration, TLSVersion, TrustStore
133
+
134
+ client = TLSClientConfiguration(trust_store=TrustStore.system(), lowest_supported_version=TLSVersion.TLSv1_3)
135
+ pinned = TLSClientConfiguration(trust_store=TrustStore.from_file("ca.pem"), client_hello=chrome)
136
+ server = TLSServerConfiguration(certificate_chain=(SigningChain((Certificate.from_file("server.pem"), PrivateKey.from_file("server.key"))),))
137
+ print(TrustStore.system()) # TrustStore(buffer=None, path=PosixPath('/etc/ssl/certs/ca-certificates.crt'), id=None)
138
+ ```
139
+
140
+ `TrustStore.system()` honors `SSL_CERT_FILE` and `SSL_CERT_DIR`, then the usual Linux and macOS bundles, and reads the ROOT and CA stores through crypt32 on Windows.
141
+
142
+ ## Proxies
143
+
144
+ ```python
145
+ from ssl2 import Proxy
146
+
147
+ proxy = Proxy.parse("socks5h://user:secret@proxy.example:1080") # http, https, socks4, socks4a, socks5, socks5h
148
+ print(proxy.scheme, proxy.host, proxy.port, proxy.credentials)
149
+ ```
150
+
151
+ `socks4` and `socks5` resolve the destination locally, `socks4a`, `socks5h` and the HTTP schemes let the proxy resolve it, and an `https` proxy carries TLS inside TLS with the same client context. A refusal raises `ProxyError` with the proxy's reason.
152
+
153
+ ## Sockets and streams on any engine
154
+
155
+ ```python
156
+ import asyncio
157
+
158
+ from ssl2 import TLSSocket, TLSStream
159
+
160
+ connection = TLSSocket.connect(context, ("www.python.org", 443), proxy=None, timeout=10)
161
+ connection.send(b"HEAD / HTTP/1.1\r\nHost: www.python.org\r\nConnection: close\r\n\r\n")
162
+ print(connection.recv(4096).split(b"\r\n", 1)[0], connection.negotiated_tls_version, connection.cipher())
163
+ connection.close()
164
+
165
+
166
+ async def main() -> None:
167
+ stream = await TLSStream.connect(context, ("www.python.org", 443), timeout=10)
168
+ await stream.write(b"HEAD / HTTP/1.1\r\nHost: www.python.org\r\nConnection: close\r\n\r\n")
169
+ print((await stream.read(4096)).split(b"\r\n", 1)[0], stream.negotiated_protocol())
170
+ await stream.close()
171
+
172
+
173
+ asyncio.run(main())
174
+ ```
175
+
176
+ `context` is an engine's `ClientContext`. A peer that drops TCP without close_notify reads as `b""`, the same default the `ssl` module has.
177
+
178
+ ## Writing an engine
179
+
180
+ An engine implements `ClientContext`, `ServerContext` and `TLSBuffer` from `ssl2.interface` and exposes `TLSImplementation(ClientContext, ServerContext, validate_config)`. `TLSSocket` and `TLSStream` drive any such `TLSBuffer`; `SessionCache` stores what the engine records.
ssl2-1.0.0/README.md ADDED
@@ -0,0 +1,172 @@
1
+ # ssl2
2
+
3
+ TLS interface for Python 3.14 after PEP 748, plus what a real client needs around it: typed IANA registries, a ClientHello model with a builder and a wire parser, JA3, JA4 and Akamai fingerprints, proxies, a blocking socket and an asyncio stream that run on any PEP 748 `TLSBuffer`, a session cache and the system trust store. Pure Python, no dependencies. The engine is a separate package, for example `boring-ssl2`.
4
+
5
+ ```text
6
+ uv add ssl2
7
+ ```
8
+
9
+ ## ClientHello model and fingerprints
10
+
11
+ ```python
12
+ from ssl2 import (
13
+ JA3,
14
+ JA4,
15
+ CertificateCompressionAlgorithm,
16
+ CipherSuite,
17
+ ClientHelloBuilder,
18
+ ECPointFormat,
19
+ ExtensionType,
20
+ NamedGroup,
21
+ NextProtocol,
22
+ ProtocolVersion,
23
+ PskKeyExchangeMode,
24
+ SignatureScheme,
25
+ )
26
+
27
+ chrome = (
28
+ ClientHelloBuilder()
29
+ .supported_versions(ProtocolVersion.TLS_1_3, ProtocolVersion.TLS_1_2)
30
+ .cipher_suites(
31
+ CipherSuite.TLS_AES_128_GCM_SHA256,
32
+ CipherSuite.TLS_AES_256_GCM_SHA384,
33
+ CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
34
+ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
35
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
36
+ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
37
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
38
+ CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
39
+ CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
40
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
41
+ CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
42
+ CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
43
+ CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384,
44
+ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
45
+ CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
46
+ )
47
+ .extensions(
48
+ ExtensionType.server_name,
49
+ ExtensionType.extended_main_secret,
50
+ ExtensionType.renegotiation_info,
51
+ ExtensionType.supported_groups,
52
+ ExtensionType.ec_point_formats,
53
+ ExtensionType.session_ticket,
54
+ ExtensionType.application_layer_protocol_negotiation,
55
+ ExtensionType.status_request,
56
+ ExtensionType.signature_algorithms,
57
+ ExtensionType.signed_certificate_timestamp,
58
+ ExtensionType.key_share,
59
+ ExtensionType.psk_key_exchange_modes,
60
+ ExtensionType.supported_versions,
61
+ ExtensionType.compress_certificate,
62
+ ExtensionType.application_settings_old,
63
+ ExtensionType.encrypted_client_hello,
64
+ )
65
+ .supported_groups(NamedGroup.X25519MLKEM768, NamedGroup.x25519, NamedGroup.secp256r1, NamedGroup.secp384r1)
66
+ .key_shares(NamedGroup.X25519MLKEM768, NamedGroup.x25519)
67
+ .ec_point_formats(ECPointFormat.uncompressed)
68
+ .signature_algorithms(
69
+ SignatureScheme.ecdsa_secp256r1_sha256,
70
+ SignatureScheme.rsa_pss_rsae_sha256,
71
+ SignatureScheme.rsa_pkcs1_sha256,
72
+ SignatureScheme.ecdsa_secp384r1_sha384,
73
+ SignatureScheme.rsa_pss_rsae_sha384,
74
+ SignatureScheme.rsa_pkcs1_sha384,
75
+ SignatureScheme.rsa_pss_rsae_sha512,
76
+ SignatureScheme.rsa_pkcs1_sha512,
77
+ )
78
+ .application_protocols(NextProtocol.H2, NextProtocol.HTTP1)
79
+ .application_settings(NextProtocol.H2)
80
+ .certificate_compression(CertificateCompressionAlgorithm.brotli)
81
+ .psk_key_exchange_modes(PskKeyExchangeMode.psk_dhe_ke)
82
+ .grease()
83
+ .build()
84
+ )
85
+ print(JA4.of(chrome).text) # t13d1516h2_8daaf6152771_02713d6af862
86
+ print(JA3.of(chrome).digest) # 5549240a5133e94d2053bfbc454228ef
87
+ ```
88
+
89
+ Every setter also takes the code point itself, so `.extensions(0, 23, 65281)` and `.cipher_suites(0x1301)` mean the same thing; that is how a captured fingerprint arrives. Unassigned and GREASE code points still parse:
90
+
91
+ ```python
92
+ from ssl2 import CipherSuite, ExtensionType
93
+
94
+ print(ExtensionType(17613).name, CipherSuite(0x1A1A).name, CipherSuite(0x1A1A).is_grease) # application_settings unassigned_0x1a1a True
95
+ ```
96
+
97
+ The parser reads a ClientHello from the TLS record or the bare handshake message, strips GREASE and sets `grease`:
98
+
99
+ ```python
100
+ from ssl2 import ClientHelloParser
101
+
102
+ hello = ClientHelloParser.parse(client_hello_bytes)
103
+ print(hello.grease, hello.cipher_suites, hello.key_share_groups)
104
+ ```
105
+
106
+ Fingerprint text forms parse back, except the hashed JA4 form:
107
+
108
+ ```python
109
+ from ssl2 import JA4, AkamaiFingerprint
110
+
111
+ ja4 = JA4.of(chrome)
112
+ print(ja4.raw) # t13d1516h2_002f,0035,...,cca9_0005,000a,...,ff01_0403,0804,...
113
+ print(JA4.parse(ja4.raw).text == ja4.text, JA4.parse(ja4.original).text == ja4.text) # True True
114
+ akamai = AkamaiFingerprint.parse("1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p")
115
+ print(akamai.digest) # 52d84b11737d980aef856699f885ca86
116
+ print(JA3.parse(JA3.of(chrome).text) == JA3.of(chrome)) # True
117
+ ```
118
+
119
+ `JA3.builder()` starts a `ClientHelloBuilder` from the JA3 fields; the payloads JA3 does not carry, such as signature schemes, key shares and ALPN, go in before `build()`.
120
+
121
+ ## Configuration, credentials, trust
122
+
123
+ ```python
124
+ from ssl2 import Certificate, PrivateKey, SigningChain, TLSClientConfiguration, TLSServerConfiguration, TLSVersion, TrustStore
125
+
126
+ client = TLSClientConfiguration(trust_store=TrustStore.system(), lowest_supported_version=TLSVersion.TLSv1_3)
127
+ pinned = TLSClientConfiguration(trust_store=TrustStore.from_file("ca.pem"), client_hello=chrome)
128
+ server = TLSServerConfiguration(certificate_chain=(SigningChain((Certificate.from_file("server.pem"), PrivateKey.from_file("server.key"))),))
129
+ print(TrustStore.system()) # TrustStore(buffer=None, path=PosixPath('/etc/ssl/certs/ca-certificates.crt'), id=None)
130
+ ```
131
+
132
+ `TrustStore.system()` honors `SSL_CERT_FILE` and `SSL_CERT_DIR`, then the usual Linux and macOS bundles, and reads the ROOT and CA stores through crypt32 on Windows.
133
+
134
+ ## Proxies
135
+
136
+ ```python
137
+ from ssl2 import Proxy
138
+
139
+ proxy = Proxy.parse("socks5h://user:secret@proxy.example:1080") # http, https, socks4, socks4a, socks5, socks5h
140
+ print(proxy.scheme, proxy.host, proxy.port, proxy.credentials)
141
+ ```
142
+
143
+ `socks4` and `socks5` resolve the destination locally, `socks4a`, `socks5h` and the HTTP schemes let the proxy resolve it, and an `https` proxy carries TLS inside TLS with the same client context. A refusal raises `ProxyError` with the proxy's reason.
144
+
145
+ ## Sockets and streams on any engine
146
+
147
+ ```python
148
+ import asyncio
149
+
150
+ from ssl2 import TLSSocket, TLSStream
151
+
152
+ connection = TLSSocket.connect(context, ("www.python.org", 443), proxy=None, timeout=10)
153
+ connection.send(b"HEAD / HTTP/1.1\r\nHost: www.python.org\r\nConnection: close\r\n\r\n")
154
+ print(connection.recv(4096).split(b"\r\n", 1)[0], connection.negotiated_tls_version, connection.cipher())
155
+ connection.close()
156
+
157
+
158
+ async def main() -> None:
159
+ stream = await TLSStream.connect(context, ("www.python.org", 443), timeout=10)
160
+ await stream.write(b"HEAD / HTTP/1.1\r\nHost: www.python.org\r\nConnection: close\r\n\r\n")
161
+ print((await stream.read(4096)).split(b"\r\n", 1)[0], stream.negotiated_protocol())
162
+ await stream.close()
163
+
164
+
165
+ asyncio.run(main())
166
+ ```
167
+
168
+ `context` is an engine's `ClientContext`. A peer that drops TCP without close_notify reads as `b""`, the same default the `ssl` module has.
169
+
170
+ ## Writing an engine
171
+
172
+ An engine implements `ClientContext`, `ServerContext` and `TLSBuffer` from `ssl2.interface` and exposes `TLSImplementation(ClientContext, ServerContext, validate_config)`. `TLSSocket` and `TLSStream` drive any such `TLSBuffer`; `SessionCache` stores what the engine records.
@@ -0,0 +1,14 @@
1
+ [project]
2
+ name = "ssl2"
3
+ version = "1.0.0"
4
+ description = "PEP 748 TLS interface: typed ClientHello model and parser, JA3, JA4 and Akamai fingerprints, proxies, sockets and asyncio streams"
5
+ readme = "README.md"
6
+ requires-python = ">=3.14.8"
7
+ dependencies = []
8
+
9
+ [project.urls]
10
+ Repository = "https://github.com/baobien-dev/ssl2"
11
+
12
+ [build-system]
13
+ requires = ["uv_build>=0.13.0,<0.14.0"]
14
+ build-backend = "uv_build"
@@ -0,0 +1,14 @@
1
+ [project]
2
+ name = "ssl2"
3
+ version = "1.0.0"
4
+ description = "PEP 748 TLS interface: typed ClientHello model and parser, JA3, JA4 and Akamai fingerprints, proxies, sockets and asyncio streams"
5
+ readme = "README.md"
6
+ requires-python = ">=3.14.8"
7
+ dependencies = []
8
+
9
+ [project.urls]
10
+ Repository = "https://github.com/baobien-dev/ssl2"
11
+
12
+ [build-system]
13
+ requires = ["uv_build>=0.13.0,<0.14.0"]
14
+ build-backend = "uv_build"
@@ -0,0 +1,106 @@
1
+ from ssl2.asynchronous import AsyncTransport, StreamTransport, TLSStream
2
+ from ssl2.client_hello import ClientHello, ClientHelloBuilder, ClientHelloParser
3
+ from ssl2.credentials import (
4
+ Certificate,
5
+ Credential,
6
+ PrivateKey,
7
+ SigningChain,
8
+ TrustStore,
9
+ )
10
+ from ssl2.errors import (
11
+ ConfigurationError,
12
+ EarlyDataRejected,
13
+ RaggedEOF,
14
+ TLSError,
15
+ WantReadError,
16
+ WantWriteError,
17
+ )
18
+ from ssl2.fingerprint import (
19
+ JA3,
20
+ JA4,
21
+ AkamaiFingerprint,
22
+ Http2Priority,
23
+ Http2Setting,
24
+ JA4Transport,
25
+ JA4Version,
26
+ PseudoHeader,
27
+ )
28
+ from ssl2.interface import (
29
+ ClientContext,
30
+ ServerContext,
31
+ SessionCache,
32
+ TLSBuffer,
33
+ TLSClientConfiguration,
34
+ TLSImplementation,
35
+ TLSServerConfiguration,
36
+ TLSSocket,
37
+ Transport,
38
+ )
39
+ from ssl2.parameters import (
40
+ CertificateCompressionAlgorithm,
41
+ CipherSuite,
42
+ CodePoint,
43
+ ECPointFormat,
44
+ ExtensionType,
45
+ Http2SettingIdentifier,
46
+ NamedGroup,
47
+ NextProtocol,
48
+ ProtocolVersion,
49
+ PskKeyExchangeMode,
50
+ SignatureScheme,
51
+ TLSVersion,
52
+ )
53
+ from ssl2.proxy import Proxy, ProxyCredentials, ProxyError, ProxyScheme
54
+
55
+ __all__ = (
56
+ "JA3",
57
+ "JA4",
58
+ "AkamaiFingerprint",
59
+ "AsyncTransport",
60
+ "Certificate",
61
+ "CertificateCompressionAlgorithm",
62
+ "CipherSuite",
63
+ "ClientContext",
64
+ "ClientHello",
65
+ "ClientHelloBuilder",
66
+ "ClientHelloParser",
67
+ "CodePoint",
68
+ "ConfigurationError",
69
+ "Credential",
70
+ "ECPointFormat",
71
+ "EarlyDataRejected",
72
+ "ExtensionType",
73
+ "Http2Priority",
74
+ "Http2Setting",
75
+ "Http2SettingIdentifier",
76
+ "JA4Transport",
77
+ "JA4Version",
78
+ "NamedGroup",
79
+ "NextProtocol",
80
+ "PrivateKey",
81
+ "ProtocolVersion",
82
+ "Proxy",
83
+ "ProxyCredentials",
84
+ "ProxyError",
85
+ "ProxyScheme",
86
+ "PseudoHeader",
87
+ "PskKeyExchangeMode",
88
+ "RaggedEOF",
89
+ "ServerContext",
90
+ "SessionCache",
91
+ "SignatureScheme",
92
+ "SigningChain",
93
+ "StreamTransport",
94
+ "TLSBuffer",
95
+ "TLSClientConfiguration",
96
+ "TLSError",
97
+ "TLSImplementation",
98
+ "TLSServerConfiguration",
99
+ "TLSSocket",
100
+ "TLSStream",
101
+ "TLSVersion",
102
+ "Transport",
103
+ "TrustStore",
104
+ "WantReadError",
105
+ "WantWriteError",
106
+ )