Development environment
Xcode 26.0 Beta 6
iOS 26 Simulator
macOS 15.6.1
To verify TLS 1.3 session resumption behavior in URLSession, I configured URLSessionConfiguration as follows and sent an HTTP GET request:
let config = URLSessionConfiguration.ephemeral
config.tlsMinimumSupportedProtocolVersion = .TLSv13
config.tlsMaximumSupportedProtocolVersion = .TLSv13
config.httpMaximumConnectionsPerHost = 1
config.httpAdditionalHeaders = ["Connection": "close"]
config.enablesEarlyData = true
let session = URLSession(configuration: config, delegate: nil, delegateQueue: nil)
let url = URL(string: "https://www.google.com")!
var request = URLRequest(url: url)
request.assumesHTTP3Capable = true
request.httpMethod = "GET"
let task = session.dataTask(with: request) { data, response, error in
if let error = error {
print("Error during URLSession data task: \(error)")
return
}
if let data = data, let responseString = String(data: data, encoding: .utf8) {
print("Received data via URLSession: \(responseString)")
} else {
print("No data received or data is not UTF-8 encoded")
}
}
task.resume()
However, after capturing the packets, I found that the ClientHello packet did not include the early_data extension.
It seems that enablesEarlyData on URLSessionConfiguration is not being applied.
How can I make this work properly?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I’m trying to use the TLS Session Resumption feature in TLS 1.2 and 1.3. I first tested this on iOS, but it didn’t work as expected. To investigate via packet capture, I ran the same code on macOS and saw the same issue.
Using URLSession to establish a WebSocket connection, I captured packets in Wireshark to check if Session Resumption was working. The behavior differed from what I expected:
1st TLS handshake – Client Hello does not contain the session_ticket extension (required for session resumption per the TLS spec).
2nd TLS handshake – Client Hello does not contain a pre_shared_key.
Test apps:
https://github.com/sf-jed-kyung/tls-session-resumption-test
Test environment: Xcode 16.3, macOS 15.6, OpenSSL 3.5.1
This repo contains:
tls-urlsession-macos – WebSocket via URLSession (shows missing extensions).
tls-openssl-macos – Manual TLS handshake via OpenSSL (shows both session_ticket and pre_shared_key).
To run this, adjust Header Search Paths and Library Search Paths for your local OpenSSL install.
URLSession – 1st Client Hello
Transport Layer Security
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 512
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 508
Version: TLS 1.2 (0x0303)
Random: 0502b10cf04223658...
Session ID Length: 32
Session ID: e3b276b14f2deaced...
Cipher Suites Length: 42
Cipher Suites (21 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 393
...
Extension: server_name (len=26) name=echo.websocket.events
Extension: extended_master_secret (len=0)
Extension: renegotiation_info (len=1)
Extension: supported_groups (len=12)
Extension: ec_point_formats (len=2)
Extension: application_layer_protocol_negotiation (len=11)
Extension: status_request (len=5)
Extension: signature_algorithms (len=22)
Extension: signed_certificate_timestamp (len=0)
Extension: key_share (len=43) x25519
Extension: psk_key_exchange_modes (len=2)
Extension: supported_versions (len=7) TLS 1.3, TLS 1.2
Extension: compress_certificate (len=3)
...
URLSession – 2nd Client Hello
Transport Layer Security
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 512
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 508
Version: TLS 1.2 (0x0303)
Random: 1e485f35ad66c8598...
Session ID Length: 32
Session ID: 99d02000c7ed403a5...
Cipher Suites Length: 42
Cipher Suites (21 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 393
...
Extension: server_name (len=26) name=echo.websocket.events
Extension: extended_master_secret (len=0)
Extension: renegotiation_info (len=1)
Extension: supported_groups (len=12)
Extension: ec_point_formats (len=2)
Extension: application_layer_protocol_negotiation (len=11)
Extension: status_request (len=5)
Extension: signature_algorithms (len=22)
Extension: signed_certificate_timestamp (len=0)
Extension: key_share (len=43) x25519
Extension: psk_key_exchange_modes (len=2)
Extension: supported_versions (len=7) TLS 1.3, TLS 1.2
Extension: compress_certificate (len=3)
...
OpenSSL – 1st Client Hello
Transport Layer Security
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 1564
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 1560
Version: TLS 1.2 (0x0303)
Random: aec30b0aad542252...
Session ID Length: 32
Session ID: f7ee7178cab8716a625...
Cipher Suites Length: 60
Cipher Suites (30 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 1427
Extension: renegotiation_info (len=1)
Extension: server_name (len=26) name=echo.websocket.events
Extension: ec_point_formats (len=4)
Extension: supported_groups (len=18)
Extension: session_ticket (len=0)
Extension: application_layer_protocol_negotiation (len=11)
Extension: encrypt_then_mac (len=0)
Extension: extended_master_secret (len=0)
Extension: signature_algorithms (len=54)
Extension: supported_versions (len=5) TLS 1.3, TLS 1.2
Extension: psk_key_exchange_modes (len=2)
Extension: key_share (len=1258) X25519MLKEM768, x25519
OpenSSL – 2nd Client Hello
Transport Layer Security
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 1716
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 1712
Version: TLS 1.2 (0x0303)
Random: 3fb3938a88166e4eb...
Session ID Length: 32
Session ID: 7f13e54a231c17ccff70...
Cipher Suites Length: 60
Cipher Suites (30 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 1579
Extension: renegotiation_info (len=1)
Extension: server_name (len=26) name=echo.websocket.events
Extension: ec_point_formats (len=4)
Extension: supported_groups (len=18)
Extension: session_ticket (len=0)
Extension: application_layer_protocol_negotiation (len=11)
Extension: encrypt_then_mac (len=0)
Extension: extended_master_secret (len=0)
Extension: signature_algorithms (len=54)
Extension: supported_versions (len=5) TLS 1.3, TLS 1.2
Extension: psk_key_exchange_modes (len=2)
Extension: key_share (len=1258) X25519MLKEM768, x25519
Extension: pre_shared_key (len=148)
Since the Client Hello is generated by the client, I believe the session_ticket should be included in the first handshake regardless of server support. However, URLSession omits it entirely.
Question: How can I enable TLS Session Resumption when using URLSession?
Topic:
App & System Services
SubTopic:
Networking