The Go Programming Language

Source file src/pkg/crypto/tls/common.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
     6	
     7	import (
     8		"crypto/rand"
     9		"crypto/rsa"
    10		"crypto/x509"
    11		"io"
    12		"io/ioutil"
    13		"sync"
    14		"time"
    15	)
    16	
    17	const (
    18		maxPlaintext    = 16384        // maximum plaintext payload length
    19		maxCiphertext   = 16384 + 2048 // maximum ciphertext payload length
    20		recordHeaderLen = 5            // record header length
    21		maxHandshake    = 65536        // maximum handshake we support (protocol max is 16 MB)
    22	
    23		minVersion = 0x0301 // minimum supported version - TLS 1.0
    24		maxVersion = 0x0301 // maximum supported version - TLS 1.0
    25	)
    26	
    27	// TLS record types.
    28	type recordType uint8
    29	
    30	const (
    31		recordTypeChangeCipherSpec recordType = 20
    32		recordTypeAlert            recordType = 21
    33		recordTypeHandshake        recordType = 22
    34		recordTypeApplicationData  recordType = 23
    35	)
    36	
    37	// TLS handshake message types.
    38	const (
    39		typeClientHello        uint8 = 1
    40		typeServerHello        uint8 = 2
    41		typeCertificate        uint8 = 11
    42		typeServerKeyExchange  uint8 = 12
    43		typeCertificateRequest uint8 = 13
    44		typeServerHelloDone    uint8 = 14
    45		typeCertificateVerify  uint8 = 15
    46		typeClientKeyExchange  uint8 = 16
    47		typeFinished           uint8 = 20
    48		typeCertificateStatus  uint8 = 22
    49		typeNextProtocol       uint8 = 67 // Not IANA assigned
    50	)
    51	
    52	// TLS compression types.
    53	const (
    54		compressionNone uint8 = 0
    55	)
    56	
    57	// TLS extension numbers
    58	var (
    59		extensionServerName      uint16 = 0
    60		extensionStatusRequest   uint16 = 5
    61		extensionSupportedCurves uint16 = 10
    62		extensionSupportedPoints uint16 = 11
    63		extensionNextProtoNeg    uint16 = 13172 // not IANA assigned
    64	)
    65	
    66	// TLS Elliptic Curves
    67	// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
    68	var (
    69		curveP256 uint16 = 23
    70		curveP384 uint16 = 24
    71		curveP521 uint16 = 25
    72	)
    73	
    74	// TLS Elliptic Curve Point Formats
    75	// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
    76	var (
    77		pointFormatUncompressed uint8 = 0
    78	)
    79	
    80	// TLS CertificateStatusType (RFC 3546)
    81	const (
    82		statusTypeOCSP uint8 = 1
    83	)
    84	
    85	// Certificate types (for certificateRequestMsg)
    86	const (
    87		certTypeRSASign    = 1 // A certificate containing an RSA key
    88		certTypeDSSSign    = 2 // A certificate containing a DSA key
    89		certTypeRSAFixedDH = 3 // A certificate containing a static DH key
    90		certTypeDSSFixedDH = 4 // A certificate containing a static DH key
    91		// Rest of these are reserved by the TLS spec
    92	)
    93	
    94	// ConnectionState records basic TLS details about the connection.
    95	type ConnectionState struct {
    96		HandshakeComplete          bool
    97		CipherSuite                uint16
    98		NegotiatedProtocol         string
    99		NegotiatedProtocolIsMutual bool
   100	
   101		// the certificate chain that was presented by the other side
   102		PeerCertificates []*x509.Certificate
   103		// the verified certificate chains built from PeerCertificates.
   104		VerifiedChains [][]*x509.Certificate
   105	}
   106	
   107	// A Config structure is used to configure a TLS client or server. After one
   108	// has been passed to a TLS function it must not be modified.
   109	type Config struct {
   110		// Rand provides the source of entropy for nonces and RSA blinding.
   111		// If Rand is nil, TLS uses the cryptographic random reader in package
   112		// crypto/rand.
   113		Rand io.Reader
   114	
   115		// Time returns the current time as the number of seconds since the epoch.
   116		// If Time is nil, TLS uses the system time.Seconds.
   117		Time func() int64
   118	
   119		// Certificates contains one or more certificate chains
   120		// to present to the other side of the connection.
   121		// Server configurations must include at least one certificate.
   122		Certificates []Certificate
   123	
   124		// RootCAs defines the set of root certificate authorities
   125		// that clients use when verifying server certificates.
   126		// If RootCAs is nil, TLS uses the host's root CA set.
   127		RootCAs *x509.CertPool
   128	
   129		// NextProtos is a list of supported, application level protocols.
   130		NextProtos []string
   131	
   132		// ServerName is included in the client's handshake to support virtual
   133		// hosting.
   134		ServerName string
   135	
   136		// AuthenticateClient controls whether a server will request a certificate
   137		// from the client. It does not require that the client send a
   138		// certificate nor does it require that the certificate sent be
   139		// anything more than self-signed.
   140		AuthenticateClient bool
   141	
   142		// CipherSuites is a list of supported cipher suites. If CipherSuites
   143		// is nil, TLS uses a list of suites supported by the implementation.
   144		CipherSuites []uint16
   145	}
   146	
   147	func (c *Config) rand() io.Reader {
   148		r := c.Rand
   149		if r == nil {
   150			return rand.Reader
   151		}
   152		return r
   153	}
   154	
   155	func (c *Config) time() int64 {
   156		t := c.Time
   157		if t == nil {
   158			t = time.Seconds
   159		}
   160		return t()
   161	}
   162	
   163	func (c *Config) rootCAs() *x509.CertPool {
   164		s := c.RootCAs
   165		if s == nil {
   166			s = defaultRoots()
   167		}
   168		return s
   169	}
   170	
   171	func (c *Config) cipherSuites() []uint16 {
   172		s := c.CipherSuites
   173		if s == nil {
   174			s = defaultCipherSuites()
   175		}
   176		return s
   177	}
   178	
   179	// A Certificate is a chain of one or more certificates, leaf first.
   180	type Certificate struct {
   181		Certificate [][]byte
   182		PrivateKey  *rsa.PrivateKey
   183		// OCSPStaple contains an optional OCSP response which will be served
   184		// to clients that request it.
   185		OCSPStaple []byte
   186	}
   187	
   188	// A TLS record.
   189	type record struct {
   190		contentType  recordType
   191		major, minor uint8
   192		payload      []byte
   193	}
   194	
   195	type handshakeMessage interface {
   196		marshal() []byte
   197		unmarshal([]byte) bool
   198	}
   199	
   200	// mutualVersion returns the protocol version to use given the advertised
   201	// version of the peer.
   202	func mutualVersion(vers uint16) (uint16, bool) {
   203		if vers < minVersion {
   204			return 0, false
   205		}
   206		if vers > maxVersion {
   207			vers = maxVersion
   208		}
   209		return vers, true
   210	}
   211	
   212	var emptyConfig Config
   213	
   214	func defaultConfig() *Config {
   215		return &emptyConfig
   216	}
   217	
   218	// Possible certificate files; stop after finding one.
   219	// On OS X we should really be using the Directory Services keychain
   220	// but that requires a lot of Mach goo to get at.  Instead we use
   221	// the same root set that curl uses.
   222	var certFiles = []string{
   223		"/etc/ssl/certs/ca-certificates.crt", // Linux etc
   224		"/usr/share/curl/curl-ca-bundle.crt", // OS X
   225	}
   226	
   227	var once sync.Once
   228	
   229	func defaultRoots() *x509.CertPool {
   230		once.Do(initDefaults)
   231		return varDefaultRoots
   232	}
   233	
   234	func defaultCipherSuites() []uint16 {
   235		once.Do(initDefaults)
   236		return varDefaultCipherSuites
   237	}
   238	
   239	func initDefaults() {
   240		initDefaultRoots()
   241		initDefaultCipherSuites()
   242	}
   243	
   244	var varDefaultRoots *x509.CertPool
   245	
   246	func initDefaultRoots() {
   247		roots := x509.NewCertPool()
   248		for _, file := range certFiles {
   249			data, err := ioutil.ReadFile(file)
   250			if err == nil {
   251				roots.AppendCertsFromPEM(data)
   252				break
   253			}
   254		}
   255		varDefaultRoots = roots
   256	}
   257	
   258	var varDefaultCipherSuites []uint16
   259	
   260	func initDefaultCipherSuites() {
   261		varDefaultCipherSuites = make([]uint16, len(cipherSuites))
   262		i := 0
   263		for id := range cipherSuites {
   264			varDefaultCipherSuites[i] = id
   265			i++
   266		}
   267	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.