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