Skip to content

Commit

Permalink
⬆️ sync: merge changes from golang/go@1.22 release branch (#280)
Browse files Browse the repository at this point in the history
Merging 229 commits from golang/go into master. 

Signed-off-by: Gaukas Wang <i@gaukas.wang>
  • Loading branch information
gaukas authored Jan 11, 2024
2 parents c209e4b + 5796f97 commit d2768e4
Show file tree
Hide file tree
Showing 18 changed files with 332 additions and 127 deletions.
70 changes: 50 additions & 20 deletions cipher_suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,13 @@ var (

// CipherSuites returns a list of cipher suites currently implemented by this
// package, excluding those with security issues, which are returned by
// InsecureCipherSuites.
// [InsecureCipherSuites].
//
// The list is sorted by ID. Note that the default cipher suites selected by
// this package might depend on logic that can't be captured by a static list,
// and might not match those returned by this function.
func CipherSuites() []*CipherSuite {
return []*CipherSuite{
{TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
{TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
{TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
{TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},

{TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false},
{TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false},
{TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false},
Expand All @@ -81,14 +76,18 @@ func CipherSuites() []*CipherSuite {
// this package and which have security issues.
//
// Most applications should not use the cipher suites in this list, and should
// only use those returned by CipherSuites.
// only use those returned by [CipherSuites].
func InsecureCipherSuites() []*CipherSuite {
// This list includes RC4, CBC_SHA256, and 3DES cipher suites. See
// cipherSuitesPreferenceOrder for details.
return []*CipherSuite{
{TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
{TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, true},
{TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, true},
{TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
{TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, true},
{TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, true},
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
Expand Down Expand Up @@ -325,23 +324,48 @@ var cipherSuitesPreferenceOrderNoAES = []uint16{
TLS_RSA_WITH_RC4_128_SHA,
}

// disabledCipherSuites are not used unless explicitly listed in
// Config.CipherSuites. They MUST be at the end of cipherSuitesPreferenceOrder.
var disabledCipherSuites = []uint16{
// disabledCipherSuites are not used unless explicitly listed in Config.CipherSuites.
var disabledCipherSuites = map[uint16]bool{
// CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: true,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: true,
TLS_RSA_WITH_AES_128_CBC_SHA256: true,

// RC4
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_RC4_128_SHA,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: true,
TLS_ECDHE_RSA_WITH_RC4_128_SHA: true,
TLS_RSA_WITH_RC4_128_SHA: true,
}

// rsaKexCiphers contains the ciphers which use RSA based key exchange,
// which we also disable by default unless a GODEBUG is set.
var rsaKexCiphers = map[uint16]bool{
TLS_RSA_WITH_RC4_128_SHA: true,
TLS_RSA_WITH_3DES_EDE_CBC_SHA: true,
TLS_RSA_WITH_AES_128_CBC_SHA: true,
TLS_RSA_WITH_AES_256_CBC_SHA: true,
TLS_RSA_WITH_AES_128_CBC_SHA256: true,
TLS_RSA_WITH_AES_128_GCM_SHA256: true,
TLS_RSA_WITH_AES_256_GCM_SHA384: true,
}

var defaultCipherSuites []uint16
var defaultCipherSuitesWithRSAKex []uint16

func init() {
defaultCipherSuites = make([]uint16, 0, len(cipherSuitesPreferenceOrder))
defaultCipherSuitesWithRSAKex = make([]uint16, 0, len(cipherSuitesPreferenceOrder))
for _, c := range cipherSuitesPreferenceOrder {
if disabledCipherSuites[c] {
continue
}
if !rsaKexCiphers[c] {
defaultCipherSuites = append(defaultCipherSuites, c)
}
defaultCipherSuitesWithRSAKex = append(defaultCipherSuitesWithRSAKex, c)
}
}

var (
defaultCipherSuitesLen = len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites)
defaultCipherSuites = cipherSuitesPreferenceOrder[:defaultCipherSuitesLen]
)

// defaultCipherSuitesTLS13 is also the preference order, since there are no
// disabled by default TLS 1.3 cipher suites. The same AES vs ChaCha20 logic as
// cipherSuitesPreferenceOrder applies.
Expand Down Expand Up @@ -535,7 +559,13 @@ func aeadAESGCMTLS13(key, nonceMask []byte) aead {
if err != nil {
panic(err)
}
aead, err := cipher.NewGCM(aes)
var aead cipher.AEAD
if boring.Enabled {
aead, err = boring.NewGCMTLS13(aes)
} else {
boring.Unreachable()
aead, err = cipher.NewGCM(aes)
}
if err != nil {
panic(err)
}
Expand Down
61 changes: 40 additions & 21 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,13 @@ type ConnectionState struct {
// ExportKeyingMaterial returns length bytes of exported key material in a new
// slice as defined in RFC 5705. If context is nil, it is not used as part of
// the seed. If the connection was set to allow renegotiation via
// Config.Renegotiation, this function will return an error.
// Config.Renegotiation, or if the connections supports neither TLS 1.3 nor
// Extended Master Secret, this function will return an error.
//
// There are conditions in which the returned values might not be unique to a
// connection. See the Security Considerations sections of RFC 5705 and RFC 7627,
// and https://mitls.org/pages/attacks/3SHAKE#channelbindings.
// Exporting key material without Extended Master Secret or TLS 1.3 was disabled
// in Go 1.22 due to security issues (see the Security Considerations sections
// of RFC 5705 and RFC 7627), but can be re-enabled with the GODEBUG setting
// tlsunsafeekm=1.
func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
return cs.ekm(label, context, length)
}
Expand Down Expand Up @@ -722,7 +724,9 @@ type Config struct {
// the list is ignored. Note that TLS 1.3 ciphersuites are not configurable.
//
// If CipherSuites is nil, a safe default list is used. The default cipher
// suites might change over time.
// suites might change over time. In Go 1.22 RSA key exchange based cipher
// suites were removed from the default list, but can be re-added with the
// GODEBUG setting tlsrsakex=1.
CipherSuites []uint16

// PreferServerCipherSuites is a legacy field and has no effect.
Expand Down Expand Up @@ -785,14 +789,11 @@ type Config struct {

// MinVersion contains the minimum TLS version that is acceptable.
//
// By default, TLS 1.2 is currently used as the minimum when acting as a
// client, and TLS 1.0 when acting as a server. TLS 1.0 is the minimum
// supported by this package, both as a client and as a server.
// By default, TLS 1.2 is currently used as the minimum. TLS 1.0 is the
// minimum supported by this package.
//
// The client-side default can temporarily be reverted to TLS 1.0 by
// including the value "x509sha1=1" in the GODEBUG environment variable.
// Note that this option will be removed in Go 1.19 (but it will still be
// possible to set this field to VersionTLS10 explicitly).
// The server-side default can be reverted to TLS 1.0 by including the value
// "tls10server=1" in the GODEBUG environment variable.
MinVersion uint16

// MaxVersion contains the maximum TLS version that is acceptable.
Expand Down Expand Up @@ -891,7 +892,7 @@ func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) {
// ticket, and the lifetime we set for all tickets we send.
const maxSessionTicketLifetime = 7 * 24 * time.Hour

// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is
// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a [Config] that is
// being used concurrently by a TLS client or server.
func (c *Config) Clone() *Config {
if c == nil {
Expand Down Expand Up @@ -1083,13 +1084,22 @@ func (c *Config) time() time.Time {
return t()
}

// var tlsrsakex = godebug.New("tlsrsakex") // [UTLS] unsupported

func (c *Config) cipherSuites() []uint16 {
if needFIPS() {
return fipsCipherSuites(c)
}
if c.CipherSuites != nil {
return c.CipherSuites
}

// [uTLS SECTION BEGIN]
// Disable unsupported godebug package
// if tlsrsakex.Value() == "1" {
// return defaultCipherSuitesWithRSAKex
// }
// [uTLS SECTION END]
return defaultCipherSuites
}

Expand All @@ -1105,15 +1115,24 @@ var supportedVersions = []uint16{
const roleClient = true
const roleServer = false

// var tls10server = godebug.New("tls10server") // [UTLS] unsupported

func (c *Config) supportedVersions(isClient bool) []uint16 {
versions := make([]uint16, 0, len(supportedVersions))
for _, v := range supportedVersions {
if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) {
continue
}
if (c == nil || c.MinVersion == 0) &&
isClient && v < VersionTLS12 {
continue
if (c == nil || c.MinVersion == 0) && v < VersionTLS12 {
// [uTLS SECTION BEGIN]
// Disable unsupported godebug package
// if isClient || tls10server.Value() != "1" {
// continue
// }
if isClient {
continue
}
// [uTLS SECTION END]
}
if c != nil && c.MinVersion != 0 && v < c.MinVersion {
continue
Expand Down Expand Up @@ -1234,9 +1253,9 @@ func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, err
// the client that sent the ClientHello. Otherwise, it returns an error
// describing the reason for the incompatibility.
//
// If this ClientHelloInfo was passed to a GetConfigForClient or GetCertificate
// callback, this method will take into account the associated Config. Note that
// if GetConfigForClient returns a different Config, the change can't be
// If this [ClientHelloInfo] was passed to a GetConfigForClient or GetCertificate
// callback, this method will take into account the associated [Config]. Note that
// if GetConfigForClient returns a different [Config], the change can't be
// accounted for by this method.
//
// This function will call x509.ParseCertificate unless c.Leaf is set, which can
Expand Down Expand Up @@ -1527,7 +1546,7 @@ type lruSessionCacheEntry struct {
state *ClientSessionState
}

// NewLRUClientSessionCache returns a ClientSessionCache with the given
// NewLRUClientSessionCache returns a [ClientSessionCache] with the given
// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
// is used instead.
func NewLRUClientSessionCache(capacity int) ClientSessionCache {
Expand Down Expand Up @@ -1576,7 +1595,7 @@ func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
c.m[sessionKey] = elem
}

// Get returns the ClientSessionState value associated with a given key. It
// Get returns the [ClientSessionState] value associated with a given key. It
// returns (nil, false) if no value is found.
func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
c.Lock()
Expand Down
52 changes: 35 additions & 17 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,21 @@ func (c *Conn) RemoteAddr() net.Addr {
}

// SetDeadline sets the read and write deadlines associated with the connection.
// A zero value for t means Read and Write will not time out.
// A zero value for t means [Conn.Read] and [Conn.Write] will not time out.
// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
func (c *Conn) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t)
}

// SetReadDeadline sets the read deadline on the underlying connection.
// A zero value for t means Read will not time out.
// A zero value for t means [Conn.Read] will not time out.
func (c *Conn) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}

// SetWriteDeadline sets the write deadline on the underlying connection.
// A zero value for t means Write will not time out.
// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
// A zero value for t means [Conn.Write] will not time out.
// After a [Conn.Write] has timed out, the TLS state is corrupt and all future writes will return the same error.
func (c *Conn) SetWriteDeadline(t time.Time) error {
return c.conn.SetWriteDeadline(t)
}
Expand Down Expand Up @@ -1184,10 +1184,10 @@ var (

// Write writes data to the connection.
//
// As Write calls Handshake, in order to prevent indefinite blocking a deadline
// must be set for both Read and Write before Write is called when the handshake
// has not yet completed. See SetDeadline, SetReadDeadline, and
// SetWriteDeadline.
// As Write calls [Conn.Handshake], in order to prevent indefinite blocking a deadline
// must be set for both [Conn.Read] and Write before Write is called when the handshake
// has not yet completed. See [Conn.SetDeadline], [Conn.SetReadDeadline], and
// [Conn.SetWriteDeadline].
func (c *Conn) Write(b []byte) (int, error) {
// interlock with Close below
for {
Expand Down Expand Up @@ -1359,10 +1359,10 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {

// Read reads data from the connection.
//
// As Read calls Handshake, in order to prevent indefinite blocking a deadline
// must be set for both Read and Write before Read is called when the handshake
// has not yet completed. See SetDeadline, SetReadDeadline, and
// SetWriteDeadline.
// As Read calls [Conn.Handshake], in order to prevent indefinite blocking a deadline
// must be set for both Read and [Conn.Write] before Read is called when the handshake
// has not yet completed. See [Conn.SetDeadline], [Conn.SetReadDeadline], and
// [Conn.SetWriteDeadline].
func (c *Conn) Read(b []byte) (int, error) {
if err := c.Handshake(); err != nil {
return 0, err
Expand Down Expand Up @@ -1446,7 +1446,7 @@ var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake com

// CloseWrite shuts down the writing side of the connection. It should only be
// called once the handshake has completed and does not call CloseWrite on the
// underlying connection. Most callers should just use Close.
// underlying connection. Most callers should just use [Conn.Close].
func (c *Conn) CloseWrite() error {
if !c.isHandshakeComplete.Load() {
return errEarlyCloseWrite
Expand Down Expand Up @@ -1474,10 +1474,15 @@ func (c *Conn) closeNotify() error {
// protocol if it has not yet been run.
//
// Most uses of this package need not call Handshake explicitly: the
// first Read or Write will call it automatically.
// first [Conn.Read] or [Conn.Write] will call it automatically.
//
// For control over canceling or setting a timeout on a handshake, use
// HandshakeContext or the Dialer's DialContext method instead.
// [Conn.HandshakeContext] or the [Dialer]'s DialContext method instead.
//
// In order to avoid denial of service attacks, the maximum RSA key size allowed
// in certificates sent by either the TLS server or client is limited to 8192
// bits. This limit can be overridden by setting tlsmaxrsasize in the GODEBUG
// environment variable (e.g. GODEBUG=tlsmaxrsasize=4096).
func (c *Conn) Handshake() error {
return c.HandshakeContext(context.Background())
}
Expand All @@ -1491,7 +1496,7 @@ func (c *Conn) Handshake() error {
// connection.
//
// Most uses of this package need not call HandshakeContext explicitly: the
// first Read or Write will call it automatically.
// first [Conn.Read] or [Conn.Write] will call it automatically.
func (c *Conn) HandshakeContext(ctx context.Context) error {
// Delegate to unexported method for named return
// without confusing documented signature.
Expand Down Expand Up @@ -1605,6 +1610,8 @@ func (c *Conn) ConnectionState() ConnectionState {
return c.connectionStateLocked()
}

// var tlsunsafeekm = godebug.New("tlsunsafeekm") // [uTLS] unsupportted

func (c *Conn) connectionStateLocked() ConnectionState {
var state ConnectionState
state.HandshakeComplete = c.isHandshakeComplete.Load()
Expand All @@ -1626,7 +1633,18 @@ func (c *Conn) connectionStateLocked() ConnectionState {
}
}
if c.config.Renegotiation != RenegotiateNever {
state.ekm = noExportedKeyingMaterial
state.ekm = noEKMBecauseRenegotiation
} else if c.vers != VersionTLS13 && !c.extMasterSecret {
state.ekm = func(label string, context []byte, length int) ([]byte, error) {
// [uTLS SECTION START]
// Disabling unsupported godebug package
// if tlsunsafeekm.Value() == "1" {
// tlsunsafeekm.IncNonDefault()
// return c.ekm(label, context, length)
// }
// [uTLS SECTION END]
return noEKMBecauseNoEMS(label, context, length)
}
} else {
state.ekm = c.ekm
}
Expand Down
Loading

0 comments on commit d2768e4

Please sign in to comment.