Unverified Commit d2768e4e authored by Gaukas Wang's avatar Gaukas Wang Committed by GitHub
Browse files

⬆️ sync: merge changes from golang/go@1.22 release branch (#280)



Merging 229 commits from golang/go into master. 

Signed-off-by: default avatarGaukas Wang <i@gaukas.wang>
parents c209e4b7 5796f973
Loading
Loading
Loading
Loading
+50 −20
Original line number Diff line number Diff line
@@ -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},
@@ -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},
@@ -325,22 +324,47 @@ 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
@@ -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)
	}
+40 −21
Original line number Diff line number Diff line
@@ -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)
}
@@ -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.
@@ -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.
@@ -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 {
@@ -1083,6 +1084,8 @@ 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)
@@ -1090,6 +1093,13 @@ func (c *Config) cipherSuites() []uint16 {
	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
}

@@ -1105,16 +1115,25 @@ 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 {
		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
		}
@@ -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
@@ -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 {
@@ -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()
+35 −17
Original line number Diff line number Diff line
@@ -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)
}
@@ -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 {
@@ -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
@@ -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
@@ -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())
}
@@ -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.
@@ -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()
@@ -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
	}

fipsonly/fipsonly.go

0 → 100644
+29 −0
Original line number Diff line number Diff line
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build boringcrypto

// Package fipsonly restricts all TLS configuration to FIPS-approved settings.
//
// The effect is triggered by importing the package anywhere in a program, as in:
//
//	import _ "crypto/tls/fipsonly"
//
// This package only exists when using Go compiled with GOEXPERIMENT=boringcrypto.
package fipsonly

// This functionality is provided as a side effect of an import to make
// it trivial to add to an existing program. It requires only a single line
// added to an existing source file, or it can be done by adding a whole
// new source file and not modifying any existing source files.

import (
	"crypto/internal/boring/fipstls"
	"crypto/internal/boring/sig"
)

func init() {
	fipstls.Force()
	sig.FIPSOnly()
}
+18 −0
Original line number Diff line number Diff line
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build boringcrypto

package fipsonly

import (
	"crypto/internal/boring/fipstls"
	"testing"
)

func Test(t *testing.T) {
	if !fipstls.Required() {
		t.Fatal("fipstls.Required() = false, must be true")
	}
}
Loading