Skip to content
Open
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
7 changes: 7 additions & 0 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,8 @@ type ClientHelloInfo struct {
// for use with SupportsCertificate.
config *Config

EncryptedClientHello []byte // [uTLS] raw outer ECH payload

// ctx is the context of the handshake that is in progress.
ctx context.Context
}
Expand Down Expand Up @@ -914,6 +916,10 @@ type Config struct {
// autoSessionTicketKeys is like sessionTicketKeys but is owned by the
// auto-rotation logic. See Config.ticketKeys.
autoSessionTicketKeys []ticketKey

// GetOscur0KeyShare gets the first keyshare, terminate the connection if
// non-nil err is returned. For use with Oscur0 only.
GetOscur0KeyShare func(*KeyShare) error // [uTLS]
}

// EncryptedClientHelloKey holds a private key that is associated
Expand Down Expand Up @@ -1020,6 +1026,7 @@ func (c *Config) Clone() *Config {
autoSessionTicketKeys: c.autoSessionTicketKeys,

PreferSkipResumptionOnNilExtension: c.PreferSkipResumptionOnNilExtension, // [UTLS]
GetOscur0KeyShare: c.GetOscur0KeyShare, // [uTLS]
}
}

Expand Down
23 changes: 12 additions & 11 deletions handshake_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,16 +994,17 @@ func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg)
}

return &ClientHelloInfo{
CipherSuites: clientHello.cipherSuites,
ServerName: clientHello.serverName,
SupportedCurves: clientHello.supportedCurves,
SupportedPoints: clientHello.supportedPoints,
SignatureSchemes: clientHello.supportedSignatureAlgorithms,
SupportedProtos: clientHello.alpnProtocols,
SupportedVersions: supportedVersions,
Extensions: clientHello.extensions,
Conn: c.conn,
config: c.config,
ctx: ctx,
CipherSuites: clientHello.cipherSuites,
ServerName: clientHello.serverName,
SupportedCurves: clientHello.supportedCurves,
SupportedPoints: clientHello.supportedPoints,
SignatureSchemes: clientHello.supportedSignatureAlgorithms,
SupportedProtos: clientHello.alpnProtocols,
SupportedVersions: supportedVersions,
Extensions: clientHello.extensions,
EncryptedClientHello: append([]byte(nil), clientHello.encryptedClientHello...), // [uTLS] expose ECH
Conn: c.conn,
config: c.config,
ctx: ctx,
}
}
5 changes: 5 additions & 0 deletions handshake_server_tls13.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {

var clientKeyShare *keyShare
for _, ks := range hs.clientHello.keyShares {
if ks.group == X25519MLKEM768 && hs.c.config.GetOscur0KeyShare != nil {
if err := hs.c.config.GetOscur0KeyShare(&KeyShare{Group: ks.group, Data: ks.data}); err != nil {
return err
}
}
if ks.group == selectedGroup {
clientKeyShare = &ks
break
Expand Down
34 changes: 29 additions & 5 deletions u_quic.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ type UQUICConn struct {
//
// The config's MinVersion must be at least TLS 1.3.
func UQUICClient(config *QUICConfig, clientHelloID ClientHelloID) *UQUICConn {
return newUQUICConn(UClient(nil, config.TLSConfig, clientHelloID))
return newUQUICConn(UClient(nil, config.TLSConfig, clientHelloID), config)
}

func newUQUICConn(uconn *UConn) *UQUICConn {
func newUQUICConn(uconn *UConn, config *QUICConfig) *UQUICConn {
uconn.quic = &quicState{
signalc: make(chan struct{}),
blockedc: make(chan struct{}),
signalc: make(chan struct{}),
blockedc: make(chan struct{}),
enableSessionEvents: config.EnableSessionEvents,
}
uconn.quic.events = uconn.quic.eventArr[:0]
return &UQUICConn{
Expand All @@ -49,7 +50,7 @@ func (q *UQUICConn) Start(ctx context.Context) error {
}
q.conn.quic.started = true
if q.conn.config.MinVersion < VersionTLS13 {
return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.13"))
return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.3"))
}
go q.conn.HandshakeContext(ctx)
if _, ok := <-q.conn.quic.blockedc; !ok {
Expand All @@ -71,6 +72,11 @@ func (q *UQUICConn) NextEvent() QUICEvent {
// to catch callers erroniously retaining it.
qs.events[last].Data[0] = 0
}
if qs.nextEvent >= len(qs.events) && qs.waitingForDrain {
qs.waitingForDrain = false
<-qs.signalc
<-qs.blockedc
}
if qs.nextEvent >= len(qs.events) {
qs.events = qs.events[:0]
qs.nextEvent = 0
Expand Down Expand Up @@ -151,6 +157,24 @@ func (q *UQUICConn) SendSessionTicket(opts QUICSessionTicketOptions) error {
return quicError(c.sendSessionTicket(opts.EarlyData, opts.Extra))
}

// StoreSession stores a session previously received in a QUICStoreSession event
// in the ClientSessionCache.
// The application may process additional events or modify the SessionState
// before storing the session.
func (q *UQUICConn) StoreSession(session *SessionState) error {
c := q.conn
if !c.isClient {
return quicError(errors.New("tls: StoreSessionTicket called on the server"))
}
cacheKey := c.clientSessionCacheKey()
if cacheKey == "" {
return nil
}
cs := &ClientSessionState{session: session}
c.config.ClientSessionCache.Put(cacheKey, cs)
return nil
}

// ConnectionState returns basic TLS details about the connection.
func (q *UQUICConn) ConnectionState() ConnectionState {
return q.conn.ConnectionState()
Expand Down