Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow BuildHandshakeState to inspect ClientHello before setting SessionTicket/PSK #301

Merged
merged 5 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions u_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,23 @@ func UClient(conn net.Conn, config *Config, clientHelloID ClientHelloID) *UConn
// [each call] marshal ClientHello.
//
// BuildHandshakeState is automatically called before uTLS performs handshake,
// amd should only be called explicitly to inspect/change fields of
// and should only be called explicitly to inspect/change fields of
// default/mimicked ClientHello.
// With the excpetion of session ticket and psk extensions, which cannot be changed
// after calling BuildHandshakeState, all other fields can be modified.
func (uconn *UConn) BuildHandshakeState() error {
return uconn.buildHandshakeState(true)
}

// BuildHandshakeStateWithoutSession is the same as BuildHandshakeState, but does not
// set the session. This is only useful when you want to inspect the ClientHello before
// setting the session manually through SetSessionTicketExtension or SetPSKExtension.
// BuildHandshakeState is automatically called before uTLS performs handshake.
func (uconn *UConn) BuildHandshakeStateWithoutSession() error {
return uconn.buildHandshakeState(false)
}

func (uconn *UConn) buildHandshakeState(loadSession bool) error {
if uconn.ClientHelloID == HelloGolang {
if uconn.clientHelloBuildStatus == BuildByGoTLS {
return nil
Expand Down Expand Up @@ -125,19 +139,23 @@ func (uconn *UConn) BuildHandshakeState() error {
return err
}

err = uconn.uLoadSession()
if err != nil {
return err
if loadSession {
err = uconn.uLoadSession()
if err != nil {
return err
}
}

err = uconn.MarshalClientHello()
if err != nil {
return err
}

uconn.uApplyPatch()
if loadSession {
uconn.uApplyPatch()
uconn.sessionController.finalCheck()
}

uconn.sessionController.finalCheck()
uconn.clientHelloBuildStatus = BuildByUtls
}
return nil
Expand Down
14 changes: 14 additions & 0 deletions u_public.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,9 @@ func (PSS PskIdentities) ToPrivate() []pskIdentity {

// ClientSessionState is public, but all its fields are private. Let's add setters, getters and constructor

// TODO! can we change this enought (or export SessionState),
// such that we wouldn't need to fork crypto/tls?

// ClientSessionState contains the state needed by clients to resume TLS sessions.
func MakeClientSessionState(
SessionTicket []uint8,
Expand All @@ -625,6 +628,7 @@ func MakeClientSessionState(
MasterSecret []byte,
ServerCertificates []*x509.Certificate,
VerifiedChains [][]*x509.Certificate) *ClientSessionState {
// TODO: Add EMS to this constructor in uTLS v2
css := &ClientSessionState{
ticket: SessionTicket,
session: &SessionState{
Expand Down Expand Up @@ -658,6 +662,10 @@ func (css *ClientSessionState) MasterSecret() []byte {
return css.session.secret
}

func (css *ClientSessionState) EMS() bool {
return css.session.extMasterSecret
}

// Certificate chain presented by the server
func (css *ClientSessionState) ServerCertificates() []*x509.Certificate {
return css.session.peerCertificates
Expand Down Expand Up @@ -689,6 +697,12 @@ func (css *ClientSessionState) SetMasterSecret(MasterSecret []byte) {
}
css.session.secret = MasterSecret
}
func (css *ClientSessionState) SetEMS(ems bool) {
if css.session == nil {
css.session = &SessionState{}
}
css.session.extMasterSecret = ems
}
func (css *ClientSessionState) SetServerCertificates(ServerCertificates []*x509.Certificate) {
if css.session == nil {
css.session = &SessionState{}
Expand Down
Loading