mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 20:57:36 +03:00
121 lines
3.9 KiB
Go
121 lines
3.9 KiB
Go
package handshake
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/marten-seemann/qtls"
|
|
)
|
|
|
|
type conn struct {
|
|
remoteAddr net.Addr
|
|
}
|
|
|
|
func newConn(remote net.Addr) net.Conn {
|
|
return &conn{remoteAddr: remote}
|
|
}
|
|
|
|
var _ net.Conn = &conn{}
|
|
|
|
func (c *conn) Read([]byte) (int, error) { return 0, nil }
|
|
func (c *conn) Write([]byte) (int, error) { return 0, nil }
|
|
func (c *conn) Close() error { return nil }
|
|
func (c *conn) RemoteAddr() net.Addr { return c.remoteAddr }
|
|
func (c *conn) LocalAddr() net.Addr { return nil }
|
|
func (c *conn) SetReadDeadline(time.Time) error { return nil }
|
|
func (c *conn) SetWriteDeadline(time.Time) error { return nil }
|
|
func (c *conn) SetDeadline(time.Time) error { return nil }
|
|
|
|
func tlsConfigToQtlsConfig(
|
|
c *tls.Config,
|
|
recordLayer qtls.RecordLayer,
|
|
extHandler tlsExtensionHandler,
|
|
getDataForSessionState func() []byte,
|
|
setDataFromSessionState func([]byte),
|
|
accept0RTT func([]byte) bool,
|
|
enable0RTT bool,
|
|
) *qtls.Config {
|
|
if c == nil {
|
|
c = &tls.Config{}
|
|
}
|
|
// Clone the config first. This executes the tls.Config.serverInit().
|
|
// This sets the SessionTicketKey, if the user didn't supply one.
|
|
c = c.Clone()
|
|
// QUIC requires TLS 1.3 or newer
|
|
minVersion := c.MinVersion
|
|
if minVersion < qtls.VersionTLS13 {
|
|
minVersion = qtls.VersionTLS13
|
|
}
|
|
maxVersion := c.MaxVersion
|
|
if maxVersion < qtls.VersionTLS13 {
|
|
maxVersion = qtls.VersionTLS13
|
|
}
|
|
var getConfigForClient func(ch *tls.ClientHelloInfo) (*qtls.Config, error)
|
|
if c.GetConfigForClient != nil {
|
|
getConfigForClient = func(ch *tls.ClientHelloInfo) (*qtls.Config, error) {
|
|
tlsConf, err := c.GetConfigForClient(ch)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if tlsConf == nil {
|
|
return nil, nil
|
|
}
|
|
return tlsConfigToQtlsConfig(tlsConf, recordLayer, extHandler, getDataForSessionState, setDataFromSessionState, accept0RTT, enable0RTT), nil
|
|
}
|
|
}
|
|
var csc qtls.ClientSessionCache
|
|
if c.ClientSessionCache != nil {
|
|
csc = newClientSessionCache(c.ClientSessionCache, getDataForSessionState, setDataFromSessionState)
|
|
}
|
|
conf := &qtls.Config{
|
|
Rand: c.Rand,
|
|
Time: c.Time,
|
|
Certificates: c.Certificates,
|
|
NameToCertificate: c.NameToCertificate,
|
|
GetCertificate: c.GetCertificate,
|
|
GetClientCertificate: c.GetClientCertificate,
|
|
GetConfigForClient: getConfigForClient,
|
|
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
|
RootCAs: c.RootCAs,
|
|
NextProtos: c.NextProtos,
|
|
EnforceNextProtoSelection: true,
|
|
ServerName: c.ServerName,
|
|
ClientAuth: c.ClientAuth,
|
|
ClientCAs: c.ClientCAs,
|
|
InsecureSkipVerify: c.InsecureSkipVerify,
|
|
CipherSuites: c.CipherSuites,
|
|
PreferServerCipherSuites: c.PreferServerCipherSuites,
|
|
SessionTicketsDisabled: c.SessionTicketsDisabled,
|
|
SessionTicketKey: c.SessionTicketKey,
|
|
ClientSessionCache: csc,
|
|
MinVersion: minVersion,
|
|
MaxVersion: maxVersion,
|
|
CurvePreferences: c.CurvePreferences,
|
|
DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
|
|
// no need to copy Renegotiation, it's not supported by TLS 1.3
|
|
KeyLogWriter: c.KeyLogWriter,
|
|
AlternativeRecordLayer: recordLayer,
|
|
GetExtensions: extHandler.GetExtensions,
|
|
ReceivedExtensions: extHandler.ReceivedExtensions,
|
|
Accept0RTT: accept0RTT,
|
|
}
|
|
if enable0RTT {
|
|
conf.Enable0RTT = true
|
|
conf.MaxEarlyData = 0xffffffff
|
|
}
|
|
return conf
|
|
}
|
|
|
|
func cipherSuiteName(id uint16) string {
|
|
switch id {
|
|
case qtls.TLS_AES_128_GCM_SHA256:
|
|
return "TLS_AES_128_GCM_SHA256"
|
|
case qtls.TLS_CHACHA20_POLY1305_SHA256:
|
|
return "TLS_CHACHA20_POLY1305_SHA256"
|
|
case qtls.TLS_AES_256_GCM_SHA384:
|
|
return "TLS_AES_256_GCM_SHA384"
|
|
default:
|
|
return "unknown cipher suite"
|
|
}
|
|
}
|