uTLS provides methods to manipulate the handshake state, such as setting custom random values or session states.
Set Client Random
Use SetClientRandom to provide a custom byte slice for the client random value:
cRandom := []byte{100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131}
tlsConn.SetClientRandom(cRandom)
Set Session State
You can create a fake session ticket using utls.MakeClientSessionState and apply it via SetSessionState:
masterSecret := make([]byte, 48)
copy(masterSecret, []byte("masterSecret is NOT sent over the wire"))
// Create a session ticket that wasn't actually issued by the server.
sessionState := utls.MakeClientSessionState(sessionTicket, uint16(tls.VersionTLS12),
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
masterSecret,
nil, nil)
tlsConn.SetSessionState(sessionState)
Manual Handshake Customization
For advanced users who need to build the state manually (e.g., using a randomized ClientHello and then adding specific extensions), use the following workflow:
- Call
BuildHandshakeState() to prepare the state. - Apply your changes to the extensions.
- Call
MarshalClientHello() to finalize the bytes that will be sent.
// 1. Build the state
err := uconn.BuildHandshakeState()
// ... apply changes to uconn.Extensions ...
// 2. Marshal final bytes
err = uconn.MarshalClientHello()
cRandom := []byte{100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131}
tlsConn.SetClientRandom(cRandom)
masterSecret := make([]byte, 48)
copy(masterSecret, []byte("masterSecret is NOT sent over the wire"))
sessionState := utls.MakeClientSessionState(sessionTicket, uint16(tls.VersionTLS12),
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
masterSecret,
nil, nil)
tlsConn.SetSessionState(sessionState)