Skip to content

Commit

Permalink
When dialing a proxy that requires session tickets, skip client hello…
Browse files Browse the repository at this point in the history
…s that don't support session tickets
  • Loading branch information
oxtoacart committed Aug 23, 2023
1 parent 192adf3 commit 5ea06d0
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
1 change: 1 addition & 0 deletions chained/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ var availableClientHelloIDs = map[string]tls.ClientHelloID{
"HelloChrome_58": tls.HelloChrome_58,
"HelloChrome_62": tls.HelloChrome_62,
"HelloChrome_102": tls.HelloChrome_102,
"HelloChrome_106": tls.HelloChrome_106_Shuffle,
"HelloEdge_Auto": tls.HelloEdge_Auto,
"Hello360_Auto": tls.Hello360_Auto,
"HelloQQ_Auto": tls.HelloQQ_Auto,
Expand Down
18 changes: 18 additions & 0 deletions chained/hello_roller.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,24 @@ func (hs helloSpec) uconn(transport net.Conn, cfg *tls.Config) (*tls.UConn, erro
return uconn, nil
}

func (hs helloSpec) supportsSessionTickets(spec *tls.ClientHelloSpec) (bool, error) {
if spec == nil {
// this can happen if we're not using a custom spec
_spec, err := tls.UTLSIdToSpec(hs.id)
if err != nil {
return false, errors.New("failed to get spec for hello %v: %v", hs.id, err)
}
spec = &_spec
}
for _, extension := range spec.Extensions {
_, isSessionTicket := extension.(*tls.SessionTicketExtension)
if isSessionTicket {
return true, nil
}
}
return false, nil
}

type helloRoller struct {
hellos []helloSpec
index, advances int
Expand Down
15 changes: 15 additions & 0 deletions chained/https_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type httpsImpl struct {
tlsConfig *tls.Config
roller *helloRoller
tlsClientHelloSplitting bool
requiresSessionTickets bool
sync.Mutex
}

Expand All @@ -45,6 +46,7 @@ func newHTTPSImpl(configDir, name, addr string, pc *config.ProxyConfig, uc commo
tlsConfig: tlsConfig,
roller: &helloRoller{hellos: hellos},
tlsClientHelloSplitting: pc.TLSClientHelloSplitting,
requiresSessionTickets: pc.TLSClientSessionState != "",
}, nil
}

Expand All @@ -59,6 +61,19 @@ func (impl *httpsImpl) dialServer(op *ops.Op, ctx context.Context) (net.Conn, er
r.advance()
return nil, errors.New("failed to generate valid utls hello spec: %v", err)
}

if impl.requiresSessionTickets && helloID != tls.HelloGolang {
supportsSessionTickets, err := currentHello.supportsSessionTickets(helloSpec)
if err != nil {
r.advance()
return nil, err
}
if !supportsSessionTickets {
r.advance()
return nil, errors.New("session ticket is required, but hello %v does not support them; advancing roller", helloID)
}
}

d := tlsdialer.Dialer{
DoDial: func(network, addr string, timeout time.Duration) (net.Conn, error) {
tcpConn, err := impl.dialCore(op, ctx, impl.addr)
Expand Down

0 comments on commit 5ea06d0

Please sign in to comment.