"crypto/x509"
        "errors"
        "fmt"
+       "internal/godebug"
        "io"
        "net"
        "strings"
        ClientSessionCache ClientSessionCache
 
        // MinVersion contains the minimum TLS version that is acceptable.
-       // If zero, TLS 1.0 is currently taken as the minimum.
+       //
+       // 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.
+       //
+       // 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).
        MinVersion uint16
 
        // MaxVersion contains the maximum TLS version that is acceptable.
-       // If zero, the maximum version supported by this package is used,
+       //
+       // By default, the maximum version supported by this package is used,
        // which is currently TLS 1.3.
        MaxVersion uint16
 
        VersionTLS10,
 }
 
-func (c *Config) supportedVersions() []uint16 {
+// debugEnableTLS10 enables TLS 1.0. See issue 45428.
+var debugEnableTLS10 = godebug.Get("tls10default") == "1"
+
+// roleClient and roleServer are meant to call supportedVersions and parents
+// with more readability at the callsite.
+const roleClient = true
+const roleServer = false
+
+func (c *Config) supportedVersions(isClient bool) []uint16 {
        versions := make([]uint16, 0, len(supportedVersions))
        for _, v := range supportedVersions {
+               if (c == nil || c.MinVersion == 0) && !debugEnableTLS10 &&
+                       isClient && v < VersionTLS12 {
+                       continue
+               }
                if c != nil && c.MinVersion != 0 && v < c.MinVersion {
                        continue
                }
        return versions
 }
 
-func (c *Config) maxSupportedVersion() uint16 {
-       supportedVersions := c.supportedVersions()
+func (c *Config) maxSupportedVersion(isClient bool) uint16 {
+       supportedVersions := c.supportedVersions(isClient)
        if len(supportedVersions) == 0 {
                return 0
        }
 
 // mutualVersion returns the protocol version to use given the advertised
 // versions of the peer. Priority is given to the peer preference order.
-func (c *Config) mutualVersion(peerVersions []uint16) (uint16, bool) {
-       supportedVersions := c.supportedVersions()
+func (c *Config) mutualVersion(isClient bool, peerVersions []uint16) (uint16, bool) {
+       supportedVersions := c.supportedVersions(isClient)
        for _, peerVersion := range peerVersions {
                for _, v := range supportedVersions {
                        if v == peerVersion {
        if config == nil {
                config = &Config{}
        }
-       vers, ok := config.mutualVersion(chi.SupportedVersions)
+       vers, ok := config.mutualVersion(roleServer, chi.SupportedVersions)
        if !ok {
                return errors.New("no mutually supported protocol versions")
        }
 
                return nil, nil, errors.New("tls: NextProtos values too large")
        }
 
-       supportedVersions := config.supportedVersions()
+       supportedVersions := config.supportedVersions(roleClient)
        if len(supportedVersions) == 0 {
                return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
        }
 
-       clientHelloVersion := config.maxSupportedVersion()
+       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 we are negotiating a protocol version that's lower than what we
        // support, check for the server downgrade canaries.
        // See RFC 8446, Section 4.1.3.
-       maxVers := c.config.maxSupportedVersion()
+       maxVers := c.config.maxSupportedVersion(roleClient)
        tls12Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS12
        tls11Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS11
        if maxVers == VersionTLS13 && c.vers <= VersionTLS12 && (tls12Downgrade || tls11Downgrade) ||
                peerVersion = serverHello.supportedVersion
        }
 
-       vers, ok := c.config.mutualVersion([]uint16{peerVersion})
+       vers, ok := c.config.mutualVersion(roleClient, []uint16{peerVersion})
        if !ok {
                c.sendAlert(alertProtocolVersion)
                return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion)
 
        if len(clientHello.supportedVersions) == 0 {
                clientVersions = supportedVersionsFromMax(clientHello.vers)
        }
-       c.vers, ok = c.config.mutualVersion(clientVersions)
+       c.vers, ok = c.config.mutualVersion(roleServer, clientVersions)
        if !ok {
                c.sendAlert(alertProtocolVersion)
                return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions)
        hs.hello.random = make([]byte, 32)
        serverRandom := hs.hello.random
        // Downgrade protection canaries. See RFC 8446, Section 4.1.3.
-       maxVers := c.config.maxSupportedVersion()
+       maxVers := c.config.maxSupportedVersion(roleServer)
        if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary {
                if c.vers == VersionTLS12 {
                        copy(serverRandom[24:], downgradeCanaryTLS12)
        for _, id := range hs.clientHello.cipherSuites {
                if id == TLS_FALLBACK_SCSV {
                        // The client is doing a fallback connection. See RFC 7507.
-                       if hs.clientHello.vers < c.config.maxSupportedVersion() {
+                       if hs.clientHello.vers < c.config.maxSupportedVersion(roleServer) {
                                c.sendAlert(alertInappropriateFallback)
                                return errors.New("tls: client using inappropriate protocol fallback")
                        }
 
        }
        clientConfig := &Config{
                InsecureSkipVerify: true,
+               MinVersion:         VersionTLS10,
        }
        state, _, err := testHandshake(t, clientConfig, serverConfig)
        if err != nil {
                t.Fatalf("handshake failed: %s", err)
        }
        if state.Version != VersionTLS11 {
-               t.Fatalf("Incorrect version %x, should be %x", state.Version, VersionTLS11)
+               t.Fatalf("incorrect version %x, should be %x", state.Version, VersionTLS11)
+       }
+
+       clientConfig.MinVersion = 0
+       _, _, err = testHandshake(t, clientConfig, serverConfig)
+       if err == nil {
+               t.Fatalf("expected failure to connect with TLS 1.0/1.1")
+       }
+
+       defer func(old bool) { debugEnableTLS10 = old }(debugEnableTLS10)
+       debugEnableTLS10 = true
+       _, _, err = testHandshake(t, clientConfig, serverConfig)
+       if err != nil {
+               t.Fatalf("handshake failed: %s", err)
+       }
+       if state.Version != VersionTLS11 {
+               t.Fatalf("incorrect version %x, should be %x", state.Version, VersionTLS11)
        }
 }
 
                InsecureSkipVerify: true,
                ClientSessionCache: NewLRUClientSessionCache(1),
                ServerName:         "servername",
+               MinVersion:         VersionTLS10,
        }
 
        // Establish a session at TLS 1.1.
 
                if id == TLS_FALLBACK_SCSV {
                        // Use c.vers instead of max(supported_versions) because an attacker
                        // could defeat this by adding an arbitrary high version otherwise.
-                       if c.vers < c.config.maxSupportedVersion() {
+                       if c.vers < c.config.maxSupportedVersion(roleServer) {
                                c.sendAlert(alertInappropriateFallback)
                                return errors.New("tls: client using inappropriate protocol fallback")
                        }
 
                Certificates:       make([]Certificate, 2),
                InsecureSkipVerify: true,
                CipherSuites:       allCipherSuites(),
+               MinVersion:         VersionTLS10,
+               MaxVersion:         VersionTLS13,
        }
        testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
        testConfig.Certificates[0].PrivateKey = testRSAPrivateKey