Copyright 2009 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.
Package tls partially implements TLS 1.2, as specified in RFC 5246, and TLS 1.3, as specified in RFC 8446.
package tls
BUG(agl): The crypto/tls package only implements some countermeasures against Lucky13 attacks on CBC-mode encryption, and only on SHA1 variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and https://www.imperialviolet.org/2013/02/04/luckythirteen.html.

import (
	
	
	
	
	
	
	
	
	
	
	
	
	
	
)
Server returns a new TLS server side connection using conn as the underlying transport. The configuration config must be non-nil and must include at least one certificate or else set GetCertificate.
func ( net.Conn,  *Config) *Conn {
	 := &Conn{
		conn:   ,
		config: ,
	}
	.handshakeFn = .serverHandshake
	return 
}
Client returns a new TLS client side connection using conn as the underlying transport. The config cannot be nil: users must set either ServerName or InsecureSkipVerify in the config.
func ( net.Conn,  *Config) *Conn {
	 := &Conn{
		conn:     ,
		config:   ,
		isClient: true,
	}
	.handshakeFn = .clientHandshake
	return 
}
A listener implements a network listener (net.Listener) for TLS connections.
type listener struct {
	net.Listener
	config *Config
}
Accept waits for and returns the next incoming TLS connection. The returned connection is of type *Conn.
func ( *listener) () (net.Conn, error) {
	,  := .Listener.Accept()
	if  != nil {
		return nil, 
	}
	return Server(, .config), nil
}
NewListener creates a Listener which accepts connections from an inner Listener and wraps each connection with Server. The configuration config must be non-nil and must include at least one certificate or else set GetCertificate.
func ( net.Listener,  *Config) net.Listener {
	 := new(listener)
	.Listener = 
	.config = 
	return 
}
Listen creates a TLS listener accepting connections on the given network address using net.Listen. The configuration config must be non-nil and must include at least one certificate or else set GetCertificate.
func (,  string,  *Config) (net.Listener, error) {
	if  == nil || len(.Certificates) == 0 &&
		.GetCertificate == nil && .GetConfigForClient == nil {
		return nil, errors.New("tls: neither Certificates, GetCertificate, nor GetConfigForClient set in Config")
	}
	,  := net.Listen(, )
	if  != nil {
		return nil, 
	}
	return NewListener(, ), nil
}

type timeoutError struct{}

func (timeoutError) () string   { return "tls: DialWithDialer timed out" }
func (timeoutError) () bool   { return true }
func (timeoutError) () bool { return true }
DialWithDialer connects to the given network address using dialer.Dial and then initiates a TLS handshake, returning the resulting TLS connection. Any timeout or deadline given in the dialer apply to connection and TLS handshake as a whole. DialWithDialer interprets a nil configuration as equivalent to the zero configuration; see the documentation of Config for the defaults.
func ( *net.Dialer, ,  string,  *Config) (*Conn, error) {
	return dial(context.Background(), , , , )
}

We want the Timeout and Deadline values from dialer to cover the whole process: TCP connection and TLS handshake. This means that we also need to start our own timers now.
	 := .Timeout

	if !.Deadline.IsZero() {
		 := time.Until(.Deadline)
		if  == 0 ||  <  {
			 = 
		}
	}
hsErrCh is non-nil if we might not wait for Handshake to complete.
	var  chan error
	if  != 0 || .Done() != nil {
		 = make(chan error, 2)
	}
	if  != 0 {
		 := time.AfterFunc(, func() {
			 <- timeoutError{}
		})
		defer .Stop()
	}

	,  := .DialContext(, , )
	if  != nil {
		return nil, 
	}

	 := strings.LastIndex(, ":")
	if  == -1 {
		 = len()
	}
	 := [:]

	if  == nil {
		 = defaultConfig()
If no ServerName is set, infer the ServerName from the hostname we're connecting to.
Make a copy to avoid polluting argument or default.
		 := .Clone()
		.ServerName = 
		 = 
	}

	 := Client(, )

	if  == nil {
		 = .Handshake()
	} else {
		go func() {
			 <- .Handshake()
		}()

		select {
		case <-.Done():
			 = .Err()
		case  = <-:
If the error was due to the context closing, prefer the context's error, rather than some random network teardown error.
				if  := .Err();  != nil {
					 = 
				}
			}
		}
	}

	if  != nil {
		.Close()
		return nil, 
	}

	return , nil
}
Dial connects to the given network address using net.Dial and then initiates a TLS handshake, returning the resulting TLS connection. Dial interprets a nil configuration as equivalent to the zero configuration; see the documentation of Config for the defaults.
func (,  string,  *Config) (*Conn, error) {
	return DialWithDialer(new(net.Dialer), , , )
}
Dialer dials TLS connections given a configuration and a Dialer for the underlying connection.
NetDialer is the optional dialer to use for the TLS connections' underlying TCP connections. A nil NetDialer is equivalent to the net.Dialer zero value.
Config is the TLS configuration to use for new connections. A nil configuration is equivalent to the zero configuration; see the documentation of Config for the defaults.
Dial connects to the given network address and initiates a TLS handshake, returning the resulting TLS connection. The returned Conn, if any, will always be of type *Conn.
func ( *Dialer) (,  string) (net.Conn, error) {
	return .DialContext(context.Background(), , )
}

func ( *Dialer) () *net.Dialer {
	if .NetDialer != nil {
		return .NetDialer
	}
	return new(net.Dialer)
}
DialContext connects to the given network address and initiates a TLS handshake, returning the resulting TLS connection. The provided Context must be non-nil. If the context expires before the connection is complete, an error is returned. Once successfully connected, any expiration of the context will not affect the connection. The returned Conn, if any, will always be of type *Conn.
func ( *Dialer) ( context.Context, ,  string) (net.Conn, error) {
	,  := dial(, .netDialer(), , , .Config)
Don't return c (a typed nil) in an interface.
		return nil, 
	}
	return , nil
}
LoadX509KeyPair reads and parses a public/private key pair from a pair of files. The files must contain PEM encoded data. The certificate file may contain intermediate certificates following the leaf certificate to form a certificate chain. On successful return, Certificate.Leaf will be nil because the parsed form of the certificate is not retained.
func (,  string) (Certificate, error) {
	,  := os.ReadFile()
	if  != nil {
		return Certificate{}, 
	}
	,  := os.ReadFile()
	if  != nil {
		return Certificate{}, 
	}
	return X509KeyPair(, )
}
X509KeyPair parses a public/private key pair from a pair of PEM encoded data. On successful return, Certificate.Leaf will be nil because the parsed form of the certificate is not retained.
func (,  []byte) (Certificate, error) {
	 := func( error) (Certificate, error) { return Certificate{},  }

	var  Certificate
	var  []string
	for {
		var  *pem.Block
		,  = pem.Decode()
		if  == nil {
			break
		}
		if .Type == "CERTIFICATE" {
			.Certificate = append(.Certificate, .Bytes)
		} else {
			 = append(, .Type)
		}
	}

	if len(.Certificate) == 0 {
		if len() == 0 {
			return (errors.New("tls: failed to find any PEM data in certificate input"))
		}
		if len() == 1 && strings.HasSuffix([0], "PRIVATE KEY") {
			return (errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched"))
		}
		return (fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", ))
	}

	 = [:0]
	var  *pem.Block
	for {
		,  = pem.Decode()
		if  == nil {
			if len() == 0 {
				return (errors.New("tls: failed to find any PEM data in key input"))
			}
			if len() == 1 && [0] == "CERTIFICATE" {
				return (errors.New("tls: found a certificate rather than a key in the PEM for the private key"))
			}
			return (fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", ))
		}
		if .Type == "PRIVATE KEY" || strings.HasSuffix(.Type, " PRIVATE KEY") {
			break
		}
		 = append(, .Type)
	}
We don't need to parse the public key for TLS, but we so do anyway to check that it looks sane and matches the private key.
	,  := x509.ParseCertificate(.Certificate[0])
	if  != nil {
		return ()
	}

	.PrivateKey,  = parsePrivateKey(.Bytes)
	if  != nil {
		return ()
	}

	switch pub := .PublicKey.(type) {
	case *rsa.PublicKey:
		,  := .PrivateKey.(*rsa.PrivateKey)
		if ! {
			return (errors.New("tls: private key type does not match public key type"))
		}
		if .N.Cmp(.N) != 0 {
			return (errors.New("tls: private key does not match public key"))
		}
	case *ecdsa.PublicKey:
		,  := .PrivateKey.(*ecdsa.PrivateKey)
		if ! {
			return (errors.New("tls: private key type does not match public key type"))
		}
		if .X.Cmp(.X) != 0 || .Y.Cmp(.Y) != 0 {
			return (errors.New("tls: private key does not match public key"))
		}
	case ed25519.PublicKey:
		,  := .PrivateKey.(ed25519.PrivateKey)
		if ! {
			return (errors.New("tls: private key type does not match public key type"))
		}
		if !bytes.Equal(.Public().(ed25519.PublicKey), ) {
			return (errors.New("tls: private key does not match public key"))
		}
	default:
		return (errors.New("tls: unknown public key algorithm"))
	}

	return , nil
}
Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates PKCS #1 private keys by default, while OpenSSL 1.0.0 generates PKCS #8 keys. OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
func ( []byte) (crypto.PrivateKey, error) {
	if ,  := x509.ParsePKCS1PrivateKey();  == nil {
		return , nil
	}
	if ,  := x509.ParsePKCS8PrivateKey();  == nil {
		switch key := .(type) {
		case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
			return , nil
		default:
			return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping")
		}
	}
	if ,  := x509.ParseECPrivateKey();  == nil {
		return , nil
	}

	return nil, errors.New("tls: failed to parse private key")