github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/src/crypto/tls/tls.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package tls partially implements TLS 1.2, as specified in RFC 5246.
     6  package tls
     7  
     8  import (
     9  	"crypto"
    10  	"crypto/ecdsa"
    11  	"crypto/rsa"
    12  	"crypto/x509"
    13  	"encoding/pem"
    14  	"errors"
    15  	"fmt"
    16  	"io/ioutil"
    17  	"net"
    18  	"strings"
    19  	"time"
    20  )
    21  
    22  // Server returns a new TLS server side connection
    23  // using conn as the underlying transport.
    24  // The configuration config must be non-nil and must include
    25  // at least one certificate or else set GetCertificate.
    26  func Server(conn net.Conn, config *Config) *Conn {
    27  	return &Conn{conn: conn, config: config}
    28  }
    29  
    30  // Client returns a new TLS client side connection
    31  // using conn as the underlying transport.
    32  // The config cannot be nil: users must set either ServerName or
    33  // InsecureSkipVerify in the config.
    34  func Client(conn net.Conn, config *Config) *Conn {
    35  	return &Conn{conn: conn, config: config, isClient: true}
    36  }
    37  
    38  // A listener implements a network listener (net.Listener) for TLS connections.
    39  type listener struct {
    40  	net.Listener
    41  	config *Config
    42  }
    43  
    44  // Accept waits for and returns the next incoming TLS connection.
    45  // The returned connection c is a *tls.Conn.
    46  func (l *listener) Accept() (c net.Conn, err error) {
    47  	c, err = l.Listener.Accept()
    48  	if err != nil {
    49  		return
    50  	}
    51  	c = Server(c, l.config)
    52  	return
    53  }
    54  
    55  // NewListener creates a Listener which accepts connections from an inner
    56  // Listener and wraps each connection with Server.
    57  // The configuration config must be non-nil and must include
    58  // at least one certificate or else set GetCertificate.
    59  func NewListener(inner net.Listener, config *Config) net.Listener {
    60  	l := new(listener)
    61  	l.Listener = inner
    62  	l.config = config
    63  	return l
    64  }
    65  
    66  // Listen creates a TLS listener accepting connections on the
    67  // given network address using net.Listen.
    68  // The configuration config must be non-nil and must include
    69  // at least one certificate or else set GetCertificate.
    70  func Listen(network, laddr string, config *Config) (net.Listener, error) {
    71  	if config == nil || (len(config.Certificates) == 0 && config.GetCertificate == nil) {
    72  		return nil, errors.New("tls: neither Certificates nor GetCertificate set in Config")
    73  	}
    74  	l, err := net.Listen(network, laddr)
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  	return NewListener(l, config), nil
    79  }
    80  
    81  type timeoutError struct{}
    82  
    83  func (timeoutError) Error() string   { return "tls: DialWithDialer timed out" }
    84  func (timeoutError) Timeout() bool   { return true }
    85  func (timeoutError) Temporary() bool { return true }
    86  
    87  // DialWithDialer connects to the given network address using dialer.Dial and
    88  // then initiates a TLS handshake, returning the resulting TLS connection. Any
    89  // timeout or deadline given in the dialer apply to connection and TLS
    90  // handshake as a whole.
    91  //
    92  // DialWithDialer interprets a nil configuration as equivalent to the zero
    93  // configuration; see the documentation of Config for the defaults.
    94  func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
    95  	// We want the Timeout and Deadline values from dialer to cover the
    96  	// whole process: TCP connection and TLS handshake. This means that we
    97  	// also need to start our own timers now.
    98  	timeout := dialer.Timeout
    99  
   100  	if !dialer.Deadline.IsZero() {
   101  		deadlineTimeout := dialer.Deadline.Sub(time.Now())
   102  		if timeout == 0 || deadlineTimeout < timeout {
   103  			timeout = deadlineTimeout
   104  		}
   105  	}
   106  
   107  	var errChannel chan error
   108  
   109  	if timeout != 0 {
   110  		errChannel = make(chan error, 2)
   111  		time.AfterFunc(timeout, func() {
   112  			errChannel <- timeoutError{}
   113  		})
   114  	}
   115  
   116  	rawConn, err := dialer.Dial(network, addr)
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  
   121  	colonPos := strings.LastIndex(addr, ":")
   122  	if colonPos == -1 {
   123  		colonPos = len(addr)
   124  	}
   125  	hostname := addr[:colonPos]
   126  
   127  	if config == nil {
   128  		config = defaultConfig()
   129  	}
   130  	// If no ServerName is set, infer the ServerName
   131  	// from the hostname we're connecting to.
   132  	if config.ServerName == "" {
   133  		// Make a copy to avoid polluting argument or default.
   134  		c := *config
   135  		c.ServerName = hostname
   136  		config = &c
   137  	}
   138  
   139  	conn := Client(rawConn, config)
   140  
   141  	if timeout == 0 {
   142  		err = conn.Handshake()
   143  	} else {
   144  		go func() {
   145  			errChannel <- conn.Handshake()
   146  		}()
   147  
   148  		err = <-errChannel
   149  	}
   150  
   151  	if err != nil {
   152  		rawConn.Close()
   153  		return nil, err
   154  	}
   155  
   156  	return conn, nil
   157  }
   158  
   159  // Dial connects to the given network address using net.Dial
   160  // and then initiates a TLS handshake, returning the resulting
   161  // TLS connection.
   162  // Dial interprets a nil configuration as equivalent to
   163  // the zero configuration; see the documentation of Config
   164  // for the defaults.
   165  func Dial(network, addr string, config *Config) (*Conn, error) {
   166  	return DialWithDialer(new(net.Dialer), network, addr, config)
   167  }
   168  
   169  // LoadX509KeyPair reads and parses a public/private key pair from a pair of
   170  // files. The files must contain PEM encoded data.
   171  func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) {
   172  	certPEMBlock, err := ioutil.ReadFile(certFile)
   173  	if err != nil {
   174  		return Certificate{}, err
   175  	}
   176  	keyPEMBlock, err := ioutil.ReadFile(keyFile)
   177  	if err != nil {
   178  		return Certificate{}, err
   179  	}
   180  	return X509KeyPair(certPEMBlock, keyPEMBlock)
   181  }
   182  
   183  // X509KeyPair parses a public/private key pair from a pair of
   184  // PEM encoded data.
   185  func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
   186  	fail := func(err error) (Certificate, error) { return Certificate{}, err }
   187  
   188  	var cert Certificate
   189  	var skippedBlockTypes []string
   190  	for {
   191  		var certDERBlock *pem.Block
   192  		certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
   193  		if certDERBlock == nil {
   194  			break
   195  		}
   196  		if certDERBlock.Type == "CERTIFICATE" {
   197  			cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
   198  		} else {
   199  			skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type)
   200  		}
   201  	}
   202  
   203  	if len(cert.Certificate) == 0 {
   204  		if len(skippedBlockTypes) == 0 {
   205  			return fail(errors.New("crypto/tls: failed to find any PEM data in certificate input"))
   206  		} else if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
   207  			return fail(errors.New("crypto/tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched"))
   208  		} else {
   209  			return fail(fmt.Errorf("crypto/tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
   210  		}
   211  	}
   212  
   213  	skippedBlockTypes = skippedBlockTypes[:0]
   214  	var keyDERBlock *pem.Block
   215  	for {
   216  		keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
   217  		if keyDERBlock == nil {
   218  			if len(skippedBlockTypes) == 0 {
   219  				return fail(errors.New("crypto/tls: failed to find any PEM data in key input"))
   220  			} else if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
   221  				return fail(errors.New("crypto/tls: found a certificate rather than a key in the PEM for the private key"))
   222  			} else {
   223  				return fail(fmt.Errorf("crypto/tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
   224  			}
   225  		}
   226  		if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
   227  			break
   228  		}
   229  		skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
   230  	}
   231  
   232  	var err error
   233  	cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
   234  	if err != nil {
   235  		return fail(err)
   236  	}
   237  
   238  	// We don't need to parse the public key for TLS, but we so do anyway
   239  	// to check that it looks sane and matches the private key.
   240  	x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
   241  	if err != nil {
   242  		return fail(err)
   243  	}
   244  
   245  	switch pub := x509Cert.PublicKey.(type) {
   246  	case *rsa.PublicKey:
   247  		priv, ok := cert.PrivateKey.(*rsa.PrivateKey)
   248  		if !ok {
   249  			return fail(errors.New("crypto/tls: private key type does not match public key type"))
   250  		}
   251  		if pub.N.Cmp(priv.N) != 0 {
   252  			return fail(errors.New("crypto/tls: private key does not match public key"))
   253  		}
   254  	case *ecdsa.PublicKey:
   255  		priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
   256  		if !ok {
   257  			return fail(errors.New("crypto/tls: private key type does not match public key type"))
   258  
   259  		}
   260  		if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
   261  			return fail(errors.New("crypto/tls: private key does not match public key"))
   262  		}
   263  	default:
   264  		return fail(errors.New("crypto/tls: unknown public key algorithm"))
   265  	}
   266  
   267  	return cert, nil
   268  }
   269  
   270  // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
   271  // PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
   272  // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
   273  func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
   274  	if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
   275  		return key, nil
   276  	}
   277  	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
   278  		switch key := key.(type) {
   279  		case *rsa.PrivateKey, *ecdsa.PrivateKey:
   280  			return key, nil
   281  		default:
   282  			return nil, errors.New("crypto/tls: found unknown private key type in PKCS#8 wrapping")
   283  		}
   284  	}
   285  	if key, err := x509.ParseECPrivateKey(der); err == nil {
   286  		return key, nil
   287  	}
   288  
   289  	return nil, errors.New("crypto/tls: failed to parse private key")
   290  }