0
# TLS Support
1
2
Modern TLS socket implementation providing secure network communications with certificate verification using OS trust stores, SNI support, session reuse, and strong cipher suites. All TLS operations use OS-native implementations.
3
4
```python
5
from oscrypto.tls import TLSSocket, TLSSession
6
from oscrypto.errors import TLSConnectionError, TLSDisconnectError, TLSVerificationError
7
```
8
9
## Capabilities
10
11
### TLS Socket
12
13
Secure socket wrapper that provides TLS encryption over TCP connections with automatic certificate verification.
14
15
```python { .api }
16
class TLSSocket:
17
def __init__(self, address: str, port: int, timeout: int = 10, session: TLSSession = None):
18
"""
19
Create a TLS socket connection.
20
21
Parameters:
22
- address: str - Server domain name or IP address for connection
23
- port: int - Server port number
24
- timeout: int - Connection timeout in seconds
25
- session: TLSSession - Optional session for reuse
26
27
Raises:
28
TLSConnectionError if connection fails
29
TLSVerificationError if certificate verification fails
30
"""
31
32
def read(self, max_length: int) -> bytes:
33
"""
34
Read data from the TLS connection.
35
36
Parameters:
37
- max_length: int - Maximum number of bytes to read
38
39
Returns:
40
Data received from the connection
41
42
Raises:
43
TLSDisconnectError if connection is closed
44
"""
45
46
def write(self, data: bytes) -> None:
47
"""
48
Write data to the TLS connection.
49
50
Parameters:
51
- data: bytes - Data to send
52
53
Raises:
54
TLSDisconnectError if connection is closed
55
"""
56
57
def select_write(self, timeout: float = None) -> bool:
58
"""
59
Check if socket is ready for writing.
60
61
Parameters:
62
- timeout: float - Timeout in seconds (None for blocking)
63
64
Returns:
65
True if socket is ready for writing
66
"""
67
68
def shutdown(self) -> None:
69
"""
70
Perform TLS close notify and shutdown the connection gracefully.
71
"""
72
73
def close(self) -> None:
74
"""
75
Close the TLS connection and underlying socket.
76
"""
77
78
@property
79
def cipher_suite(self) -> str:
80
"""Get the negotiated cipher suite name."""
81
82
@property
83
def protocol(self) -> str:
84
"""Get the negotiated TLS protocol version."""
85
86
@property
87
def compression(self) -> bool:
88
"""Get whether TLS compression is enabled."""
89
90
@property
91
def session_id(self) -> bytes:
92
"""Get the TLS session ID for session reuse."""
93
94
@property
95
def session_ticket(self) -> bytes:
96
"""Get the TLS session ticket for session reuse."""
97
98
@property
99
def hostname(self) -> str:
100
"""Get the server hostname."""
101
102
@property
103
def port(self) -> int:
104
"""Get the server port."""
105
106
@property
107
def certificate(self) -> Certificate:
108
"""Get the server's certificate."""
109
110
@property
111
def intermediates(self) -> List[Certificate]:
112
"""Get intermediate certificates from the server."""
113
```
114
115
### TLS Session
116
117
Session manager for TLS connection reuse and configuration.
118
119
```python { .api }
120
class TLSSession:
121
def __init__(self, protocol: str = None, manual_validation: bool = False,
122
extra_trust_roots: List[Certificate] = None):
123
"""
124
Create a TLS session for connection reuse and configuration.
125
126
Parameters:
127
- protocol: str - TLS protocol version ('TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3')
128
- manual_validation: bool - Disable automatic certificate validation
129
- extra_trust_roots: List[Certificate] - Additional CA certificates to trust
130
131
"""
132
133
@property
134
def protocol(self) -> str:
135
"""Get the configured TLS protocol version."""
136
137
@property
138
def manual_validation(self) -> bool:
139
"""Get whether manual validation is enabled."""
140
141
@property
142
def extra_trust_roots(self) -> List[Certificate]:
143
"""Get the list of extra trust root certificates."""
144
```
145
146
## Usage Examples
147
148
### Basic HTTPS Request
149
150
```python
151
from oscrypto import tls
152
153
# Create TLS connection to HTTPS server
154
socket = tls.TLSSocket('www.example.com', 443)
155
156
# Send HTTP request
157
request = b'GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: close\r\n\r\n'
158
socket.write(request)
159
160
# Read response
161
response = b''
162
while True:
163
try:
164
data = socket.read(1024)
165
if not data:
166
break
167
response += data
168
except tls.TLSDisconnectError:
169
break
170
171
socket.close()
172
173
print(f"Response length: {len(response)} bytes")
174
print(f"Server certificate: {socket.certificate.subject}")
175
```
176
177
### Session Reuse
178
179
```python
180
from oscrypto import tls
181
182
# Create a session for connection reuse
183
session = tls.TLSSession()
184
185
# First connection
186
socket1 = tls.TLSSocket('api.example.com', 443, session=session)
187
socket1.write(b'GET /endpoint1 HTTP/1.1\r\nHost: api.example.com\r\n\r\n')
188
response1 = socket1.read(1024)
189
socket1.close()
190
191
# Second connection reuses the session
192
socket2 = tls.TLSSocket('api.example.com', 443, session=session)
193
socket2.write(b'GET /endpoint2 HTTP/1.1\r\nHost: api.example.com\r\n\r\n')
194
response2 = socket2.read(1024)
195
socket2.close()
196
197
print(f"Session ID: {socket1.session_id.hex()}")
198
print(f"Cipher suite: {socket1.cipher_suite}")
199
print(f"Protocol: {socket1.protocol}")
200
```
201
202
### Custom Certificate Validation
203
204
```python
205
from oscrypto import tls, asymmetric
206
207
# Load custom CA certificate
208
with open('custom_ca.pem', 'rb') as f:
209
custom_ca = asymmetric.load_certificate(f.read())
210
211
# Create session with custom trust roots
212
session = tls.TLSSession(extra_trust_roots=[custom_ca])
213
214
# Connect to server using custom CA
215
socket = tls.TLSSocket('internal.company.com', 443, session=session)
216
217
# Connection will now trust the custom CA
218
socket.write(b'GET / HTTP/1.1\r\nHost: internal.company.com\r\n\r\n')
219
response = socket.read(1024)
220
socket.close()
221
```
222
223
### Manual Certificate Validation
224
225
```python
226
from oscrypto import tls, errors
227
228
# Create session with manual validation
229
session = tls.TLSSession(manual_validation=True)
230
231
try:
232
socket = tls.TLSSocket('untrusted.example.com', 443, session=session)
233
234
# Manually inspect the certificate
235
cert = socket.certificate
236
print(f"Certificate subject: {cert.subject}")
237
print(f"Certificate issuer: {cert.issuer}")
238
print(f"Certificate valid from: {cert.not_valid_before}")
239
print(f"Certificate valid until: {cert.not_valid_after}")
240
241
# Proceed with connection (validation bypassed)
242
socket.write(b'GET / HTTP/1.1\r\nHost: untrusted.example.com\r\n\r\n')
243
response = socket.read(1024)
244
socket.close()
245
246
except errors.TLSVerificationError as e:
247
print(f"Certificate verification failed: {e}")
248
print(f"Server certificate: {e.certificate.subject}")
249
```
250
251
### Error Handling
252
253
```python
254
from oscrypto import tls, errors
255
import socket
256
257
try:
258
tls_socket = tls.TLSSocket('example.com', 443, timeout=5)
259
tls_socket.write(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
260
261
while True:
262
try:
263
data = tls_socket.read(1024)
264
if not data:
265
break
266
print(f"Received {len(data)} bytes")
267
except errors.TLSGracefulDisconnectError:
268
# Server closed connection gracefully
269
print("Server closed connection")
270
break
271
except errors.TLSDisconnectError:
272
# Unexpected disconnection
273
print("Connection lost unexpectedly")
274
break
275
276
except errors.TLSConnectionError as e:
277
print(f"Connection failed: {e}")
278
except errors.TLSVerificationError as e:
279
print(f"Certificate verification failed: {e}")
280
print(f"Certificate subject: {e.certificate.subject}")
281
except socket.timeout:
282
print("Connection timed out")
283
finally:
284
if 'tls_socket' in locals():
285
tls_socket.close()
286
```