TUN-8006: Update quic-go to latest upstream

This commit is contained in:
Chung-Ting
2023-12-04 09:49:00 +00:00
parent 45236a1f7d
commit 8068cdebb6
219 changed files with 10032 additions and 17038 deletions

View File

@@ -57,23 +57,12 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error)
return nil, nil, errors.New("tls: NextProtos values too large")
}
var supportedVersions []uint16
var clientHelloVersion uint16
if c.extraConfig.usesAlternativeRecordLayer() {
if config.maxSupportedVersion(roleClient) < VersionTLS13 {
return nil, nil, errors.New("tls: MaxVersion prevents QUIC from using TLS 1.3")
}
// Only offer TLS 1.3 when QUIC is used.
supportedVersions = []uint16{VersionTLS13}
clientHelloVersion = VersionTLS13
} else {
supportedVersions = config.supportedVersions(roleClient)
if len(supportedVersions) == 0 {
return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
}
clientHelloVersion = config.maxSupportedVersion(roleClient)
supportedVersions := config.supportedVersions(roleClient)
if len(supportedVersions) == 0 {
return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
}
clientHelloVersion := config.maxSupportedVersion(roleClient)
// The version at the beginning of the ClientHello was capped at TLS 1.2
// for compatibility reasons. The supported_versions extension is used
// to negotiate versions now. See RFC 8446, Section 4.2.1.
@@ -127,7 +116,9 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error)
// A random session ID is used to detect when the server accepted a ticket
// and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as
// a compatibility measure (see RFC 8446, Section 4.1.2).
if c.extraConfig == nil || c.extraConfig.AlternativeRecordLayer == nil {
//
// The session ID is not set for QUIC connections (see RFC 9001, Section 8.4).
if c.quic == nil {
hello.sessionId = make([]byte, 32)
if _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil {
return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
@@ -143,6 +134,9 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error)
var secret clientKeySharePrivate
if hello.supportedVersions[0] == VersionTLS13 {
if len(hello.supportedVersions) == 1 {
hello.cipherSuites = hello.cipherSuites[:0]
}
if hasAESGCMHardwareSupport {
hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
} else {
@@ -176,8 +170,15 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error)
}
}
if hello.supportedVersions[0] == VersionTLS13 && c.extraConfig != nil && c.extraConfig.GetExtensions != nil {
hello.additionalExtensions = c.extraConfig.GetExtensions(typeClientHello)
if c.quic != nil {
p, err := c.quicGetTransportParameters()
if err != nil {
return nil, nil, err
}
if p == nil {
p = []byte{}
}
hello.quicTransportParameters = p
}
return hello, secret, nil
@@ -187,7 +188,6 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
if c.config == nil {
c.config = fromConfig(defaultConfig())
}
c.setAlternativeRecordLayer()
// This may be a renegotiation handshake, in which case some fields
// need to be reset.
@@ -204,45 +204,33 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
return err
}
if cacheKey != "" && session != nil {
var deletedTicket bool
if session.vers == VersionTLS13 && hello.earlyData && c.extraConfig != nil && c.extraConfig.Enable0RTT {
// don't reuse a session ticket that enabled 0-RTT
c.config.ClientSessionCache.Put(cacheKey, nil)
deletedTicket = true
if suite := cipherSuiteTLS13ByID(session.cipherSuite); suite != nil {
h := suite.hash.New()
helloBytes, err := hello.marshal()
if err != nil {
return err
}
h.Write(helloBytes)
clientEarlySecret := suite.deriveSecret(earlySecret, "c e traffic", h)
c.out.exportKey(Encryption0RTT, suite, clientEarlySecret)
if err := c.config.writeKeyLog(keyLogLabelEarlyTraffic, hello.random, clientEarlySecret); err != nil {
return err
}
defer func() {
// If we got a handshake failure when resuming a session, throw away
// the session ticket. See RFC 5077, Section 3.2.
//
// RFC 8446 makes no mention of dropping tickets on failure, but it
// does require servers to abort on invalid binders, so we need to
// delete tickets to recover from a corrupted PSK.
if err != nil {
c.config.ClientSessionCache.Put(cacheKey, nil)
}
}
if !deletedTicket {
defer func() {
// If we got a handshake failure when resuming a session, throw away
// the session ticket. See RFC 5077, Section 3.2.
//
// RFC 8446 makes no mention of dropping tickets on failure, but it
// does require servers to abort on invalid binders, so we need to
// delete tickets to recover from a corrupted PSK.
if err != nil {
c.config.ClientSessionCache.Put(cacheKey, nil)
}
}()
}
}()
}
if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
return err
}
if hello.earlyData {
suite := cipherSuiteTLS13ByID(session.cipherSuite)
transcript := suite.hash.New()
if err := transcriptMsg(hello, transcript); err != nil {
return err
}
earlyTrafficSecret := suite.deriveSecret(earlySecret, clientEarlyTrafficLabel, transcript)
c.quicSetWriteSecret(QUICEncryptionLevelEarly, suite.id, earlyTrafficSecret)
}
// serverHelloMsg is not included in the transcript
msg, err := c.readHandshake(nil)
if err != nil {
@@ -305,7 +293,6 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
c.config.ClientSessionCache.Put(cacheKey, toClientSessionState(hs.session))
}
c.updateConnectionState()
return nil
}
@@ -358,7 +345,10 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
}
// Try to resume a previously negotiated TLS session, if available.
cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
cacheKey = c.clientSessionCacheKey()
if cacheKey == "" {
return "", nil, nil, nil, nil
}
sess, ok := c.config.ClientSessionCache.Get(cacheKey)
if !ok || sess == nil {
return cacheKey, nil, nil, nil, nil
@@ -442,6 +432,17 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
return cacheKey, nil, nil, nil, nil
}
if c.quic != nil && maxEarlyData > 0 {
var earlyData bool
if session.vers == VersionTLS13 && c.extraConfig != nil && c.extraConfig.SetAppDataFromSessionState != nil {
earlyData = c.extraConfig.SetAppDataFromSessionState(appData)
}
// For 0-RTT, the cipher suite has to match exactly.
if earlyData && mutualCipherSuiteTLS13(hello.cipherSuites, session.cipherSuite) != nil {
hello.earlyData = true
}
}
// Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
ticketAge := uint32(c.config.time().Sub(session.receivedAt) / time.Millisecond)
identity := pskIdentity{
@@ -456,9 +457,6 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
session.nonce, cipherSuite.hash.Size())
earlySecret = cipherSuite.extract(psk, nil)
binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil)
if c.extraConfig != nil {
hello.earlyData = c.extraConfig.Enable0RTT && maxEarlyData > 0
}
transcript := cipherSuite.hash.New()
helloBytes, err := hello.marshalWithoutBinders()
if err != nil {
@@ -470,9 +468,6 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
return "", nil, nil, nil, err
}
if session.vers == VersionTLS13 && c.extraConfig != nil && c.extraConfig.SetAppDataFromSessionState != nil {
c.extraConfig.SetAppDataFromSessionState(appData)
}
return
}
@@ -827,7 +822,7 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
}
}
if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol); err != nil {
if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol, false); err != nil {
c.sendAlert(alertUnsupportedExtension)
return false, err
}
@@ -865,8 +860,12 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
// checkALPN ensure that the server's choice of ALPN protocol is compatible with
// the protocols that we advertised in the Client Hello.
func checkALPN(clientProtos []string, serverProto string) error {
func checkALPN(clientProtos []string, serverProto string, quic bool) error {
if serverProto == "" {
if quic && len(clientProtos) > 0 {
// RFC 9001, Section 8.1
return errors.New("tls: server did not select an ALPN protocol")
}
return nil
}
if len(clientProtos) == 0 {
@@ -962,6 +961,10 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error {
return nil
}
// maxRSAKeySize is the maximum RSA key size in bits that we are willing
// to verify the signatures of during a TLS handshake.
const maxRSAKeySize = 8192
// verifyServerCertificate parses and verifies the provided chain, setting
// c.verifiedChains and c.peerCertificates or sending the appropriate alert.
func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
@@ -973,6 +976,10 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
c.sendAlert(alertBadCertificate)
return errors.New("tls: failed to parse certificate from server: " + err.Error())
}
if cert.cert.PublicKeyAlgorithm == x509.RSA && cert.cert.PublicKey.(*rsa.PublicKey).N.BitLen() > maxRSAKeySize {
c.sendAlert(alertBadCertificate)
return fmt.Errorf("tls: server sent certificate containing RSA key larger than %d bits", maxRSAKeySize)
}
activeHandles[i] = cert
certs[i] = cert.cert
}
@@ -1106,15 +1113,16 @@ func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate,
return new(Certificate), nil
}
const clientSessionCacheKeyPrefix = "qtls-"
// clientSessionCacheKey returns a key used to cache sessionTickets that could
// be used to resume previously negotiated TLS sessions with a server.
func clientSessionCacheKey(serverAddr net.Addr, config *config) string {
if len(config.ServerName) > 0 {
return clientSessionCacheKeyPrefix + config.ServerName
func (c *Conn) clientSessionCacheKey() string {
if len(c.config.ServerName) > 0 {
return c.config.ServerName
}
return clientSessionCacheKeyPrefix + serverAddr.String()
if c.conn != nil {
return c.conn.RemoteAddr().String()
}
return ""
}
// hostnameInSNI converts name into an appropriate hostname for SNI.