sync: Go 1.21 with QUIC support (#208)

* sync: Go 1.21rc3, QUIC support added (#207)

* sync: merge with upstream tag/go-1.21rc3 (#11)

* fix: all tests pass

* impl: UQUIC Transport

* deps: bump up min Go version

* new: uquic

* fix: add QUICTransportParameter

* deprecated: Go 1.19 no longer supported

Go 1.19 will fail to build or pass the test once we bump up to the new version.

* sync: crypto/tls: restrict RSA keys in certificates to <= 8192 bits (#209)

* [release-branch.go1.21] crypto/tls: restrict RSA keys in certificates to <= 8192 bits

Extremely large RSA keys in certificate chains can cause a client/server
to expend significant CPU time verifying signatures. Limit this by
restricting the size of RSA keys transmitted during handshakes to <=
8192 bits.

Based on a survey of publicly trusted RSA keys, there are currently only
three certificates in circulation with keys larger than this, and all
three appear to be test certificates that are not actively deployed. It
is possible there are larger keys in use in private PKIs, but we target
the web PKI, so causing breakage here in the interests of increasing the
default safety of users of crypto/tls seems reasonable.

Thanks to Mateusz Poliwczak for reporting this issue.

Fixes CVE-2023-29409

* build: [ci skip] boring not included

* fix: typo [ci skip]

* docs: replenish readme [ci skip]

replace old build status badge with new ones, bump up required version noted in docs, update developer contact to reflect current status.
This commit is contained in:
Gaukas Wang 2023-08-03 23:22:53 -06:00 committed by GitHub
parent d73321bb14
commit 86e9b69fdd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
150 changed files with 13344 additions and 10239 deletions

View file

@ -7,6 +7,7 @@ package tls
import (
"bytes"
"compress/zlib"
"crypto/ecdh"
"errors"
"fmt"
"io"
@ -162,3 +163,138 @@ func (hs *clientHandshakeStateTLS13) utlsReadServerParameters(encryptedExtension
return nil
}
func (c *Conn) makeClientHelloForApplyPreset() (*clientHelloMsg, *ecdh.PrivateKey, error) {
config := c.config
// [UTLS SECTION START]
if len(config.ServerName) == 0 && !config.InsecureSkipVerify && len(config.InsecureServerNameToVerify) == 0 {
return nil, nil, errors.New("tls: at least one of ServerName, InsecureSkipVerify or InsecureServerNameToVerify must be specified in the tls.Config")
}
// [UTLS SECTION END]
nextProtosLength := 0
for _, proto := range config.NextProtos {
if l := len(proto); l == 0 || l > 255 {
return nil, nil, errors.New("tls: invalid NextProtos value")
} else {
nextProtosLength += 1 + l
}
}
if nextProtosLength > 0xffff {
return nil, nil, errors.New("tls: NextProtos values too large")
}
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.
if clientHelloVersion > VersionTLS12 {
clientHelloVersion = VersionTLS12
}
hello := &clientHelloMsg{
vers: clientHelloVersion,
compressionMethods: []uint8{compressionNone},
random: make([]byte, 32),
extendedMasterSecret: true,
ocspStapling: true,
scts: true,
serverName: hostnameInSNI(config.ServerName),
supportedCurves: config.curvePreferences(),
supportedPoints: []uint8{pointFormatUncompressed},
secureRenegotiationSupported: true,
alpnProtocols: config.NextProtos,
supportedVersions: supportedVersions,
}
if c.handshakes > 0 {
hello.secureRenegotiation = c.clientFinished[:]
}
preferenceOrder := cipherSuitesPreferenceOrder
if !hasAESGCMHardwareSupport {
preferenceOrder = cipherSuitesPreferenceOrderNoAES
}
configCipherSuites := config.cipherSuites()
hello.cipherSuites = make([]uint16, 0, len(configCipherSuites))
for _, suiteId := range preferenceOrder {
suite := mutualCipherSuite(configCipherSuites, suiteId)
if suite == nil {
continue
}
// Don't advertise TLS 1.2-only cipher suites unless
// we're attempting TLS 1.2.
if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
continue
}
hello.cipherSuites = append(hello.cipherSuites, suiteId)
}
_, err := io.ReadFull(config.rand(), hello.random)
if err != nil {
return nil, nil, errors.New("tls: short read from Rand: " + err.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).
//
// 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())
}
}
if hello.vers >= VersionTLS12 {
hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
}
if testingOnlyForceClientHelloSignatureAlgorithms != nil {
hello.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
}
var key *ecdh.PrivateKey
if hello.supportedVersions[0] == VersionTLS13 {
// Reset the list of ciphers when the client only supports TLS 1.3.
if len(hello.supportedVersions) == 1 {
hello.cipherSuites = nil
}
if hasAESGCMHardwareSupport {
hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
} else {
hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
}
curveID := config.curvePreferences()[0]
if _, ok := curveForCurveID(curveID); !ok {
return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
}
key, err = generateECDHEKey(config.rand(), curveID)
if err != nil {
return nil, nil, err
}
hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
}
// [UTLS] We don't need this, since it is not ready yet
// 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, key, nil
}