src/pkg/crypto/tls/tls.go - The Go Programming Language

Golang

Source file src/pkg/crypto/tls/tls.go

     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.0, as specified in RFC 2246.
     6	package tls
     7	
     8	import (
     9		"crypto/rsa"
    10		"crypto/x509"
    11		"encoding/pem"
    12		"errors"
    13		"io/ioutil"
    14		"net"
    15		"strings"
    16	)
    17	
    18	// Server returns a new TLS server side connection
    19	// using conn as the underlying transport.
    20	// The configuration config must be non-nil and must have
    21	// at least one certificate.
    22	func Server(conn net.Conn, config *Config) *Conn {
    23		return &Conn{conn: conn, config: config}
    24	}
    25	
    26	// Client returns a new TLS client side connection
    27	// using conn as the underlying transport.
    28	// Client interprets a nil configuration as equivalent to
    29	// the zero configuration; see the documentation of Config
    30	// for the defaults.
    31	func Client(conn net.Conn, config *Config) *Conn {
    32		return &Conn{conn: conn, config: config, isClient: true}
    33	}
    34	
    35	// A listener implements a network listener (net.Listener) for TLS connections.
    36	type listener struct {
    37		net.Listener
    38		config *Config
    39	}
    40	
    41	// Accept waits for and returns the next incoming TLS connection.
    42	// The returned connection c is a *tls.Conn.
    43	func (l *listener) Accept() (c net.Conn, err error) {
    44		c, err = l.Listener.Accept()
    45		if err != nil {
    46			return
    47		}
    48		c = Server(c, l.config)
    49		return
    50	}
    51	
    52	// NewListener creates a Listener which accepts connections from an inner
    53	// Listener and wraps each connection with Server.
    54	// The configuration config must be non-nil and must have
    55	// at least one certificate.
    56	func NewListener(inner net.Listener, config *Config) net.Listener {
    57		l := new(listener)
    58		l.Listener = inner
    59		l.config = config
    60		return l
    61	}
    62	
    63	// Listen creates a TLS listener accepting connections on the
    64	// given network address using net.Listen.
    65	// The configuration config must be non-nil and must have
    66	// at least one certificate.
    67	func Listen(network, laddr string, config *Config) (net.Listener, error) {
    68		if config == nil || len(config.Certificates) == 0 {
    69			return nil, errors.New("tls.Listen: no certificates in configuration")
    70		}
    71		l, err := net.Listen(network, laddr)
    72		if err != nil {
    73			return nil, err
    74		}
    75		return NewListener(l, config), nil
    76	}
    77	
    78	// Dial connects to the given network address using net.Dial
    79	// and then initiates a TLS handshake, returning the resulting
    80	// TLS connection.
    81	// Dial interprets a nil configuration as equivalent to
    82	// the zero configuration; see the documentation of Config
    83	// for the defaults.
    84	func Dial(network, addr string, config *Config) (*Conn, error) {
    85		raddr := addr
    86		c, err := net.Dial(network, raddr)
    87		if err != nil {
    88			return nil, err
    89		}
    90	
    91		colonPos := strings.LastIndex(raddr, ":")
    92		if colonPos == -1 {
    93			colonPos = len(raddr)
    94		}
    95		hostname := raddr[:colonPos]
    96	
    97		if config == nil {
    98			config = defaultConfig()
    99		}
   100		// If no ServerName is set, infer the ServerName
   101		// from the hostname we're connecting to.
   102		if config.ServerName == "" {
   103			// Make a copy to avoid polluting argument or default.
   104			c := *config
   105			c.ServerName = hostname
   106			config = &c
   107		}
   108		conn := Client(c, config)
   109		if err = conn.Handshake(); err != nil {
   110			c.Close()
   111			return nil, err
   112		}
   113		return conn, nil
   114	}
   115	
   116	// LoadX509KeyPair reads and parses a public/private key pair from a pair of
   117	// files. The files must contain PEM encoded data.
   118	func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) {
   119		certPEMBlock, err := ioutil.ReadFile(certFile)
   120		if err != nil {
   121			return
   122		}
   123		keyPEMBlock, err := ioutil.ReadFile(keyFile)
   124		if err != nil {
   125			return
   126		}
   127		return X509KeyPair(certPEMBlock, keyPEMBlock)
   128	}
   129	
   130	// X509KeyPair parses a public/private key pair from a pair of
   131	// PEM encoded data.
   132	func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) {
   133		var certDERBlock *pem.Block
   134		for {
   135			certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
   136			if certDERBlock == nil {
   137				break
   138			}
   139			if certDERBlock.Type == "CERTIFICATE" {
   140				cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
   141			}
   142		}
   143	
   144		if len(cert.Certificate) == 0 {
   145			err = errors.New("crypto/tls: failed to parse certificate PEM data")
   146			return
   147		}
   148	
   149		keyDERBlock, _ := pem.Decode(keyPEMBlock)
   150		if keyDERBlock == nil {
   151			err = errors.New("crypto/tls: failed to parse key PEM data")
   152			return
   153		}
   154	
   155		// OpenSSL 0.9.8 generates PKCS#1 private keys by default, while
   156		// OpenSSL 1.0.0 generates PKCS#8 keys. We try both.
   157		var key *rsa.PrivateKey
   158		if key, err = x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes); err != nil {
   159			var privKey interface{}
   160			if privKey, err = x509.ParsePKCS8PrivateKey(keyDERBlock.Bytes); err != nil {
   161				err = errors.New("crypto/tls: failed to parse key: " + err.Error())
   162				return
   163			}
   164	
   165			var ok bool
   166			if key, ok = privKey.(*rsa.PrivateKey); !ok {
   167				err = errors.New("crypto/tls: found non-RSA private key in PKCS#8 wrapping")
   168				return
   169			}
   170		}
   171	
   172		cert.PrivateKey = key
   173	
   174		// We don't need to parse the public key for TLS, but we so do anyway
   175		// to check that it looks sane and matches the private key.
   176		x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
   177		if err != nil {
   178			return
   179		}
   180	
   181		if x509Cert.PublicKeyAlgorithm != x509.RSA || x509Cert.PublicKey.(*rsa.PublicKey).N.Cmp(key.PublicKey.N) != 0 {
   182			err = errors.New("crypto/tls: private key does not match public key")
   183			return
   184		}
   185	
   186		return
   187	}