blob: bfe331dd429fe71dc4a9ecf04b286bb813db1696 [file] [log] [blame]
Adam Langley950f2632009-11-05 16:43:29 -08001// 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
Frithjof Schulze4d7c6352013-10-02 12:09:13 -04005// Package tls partially implements TLS 1.2, as specified in RFC 5246.
Adam Langley950f2632009-11-05 16:43:29 -08006package tls
7
Brad Fitzpatrick91abab02015-12-08 16:49:17 +00008// BUG(agl): The crypto/tls package does not implement countermeasures
9// against Lucky13 attacks on CBC-mode encryption. See
10// http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and
11// https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
12
Adam Langley950f2632009-11-05 16:43:29 -080013import (
Joel Singaaf3b712012-11-16 19:33:59 +110014 "crypto"
15 "crypto/ecdsa"
Adam Langley836529a2010-11-05 09:54:56 -040016 "crypto/rsa"
17 "crypto/x509"
18 "encoding/pem"
Russ Coxc2049d22011-11-01 22:04:37 -040019 "errors"
Adam Langleybe160012015-08-30 10:23:30 -070020 "fmt"
Adam Langleyfc23def2010-07-02 13:00:18 -040021 "io/ioutil"
Robert Griesemer5a1d3322009-12-15 15:33:31 -080022 "net"
Adam Langley836529a2010-11-05 09:54:56 -040023 "strings"
Adam Langley1f8b2a62014-02-28 09:40:12 -050024 "time"
Adam Langley950f2632009-11-05 16:43:29 -080025)
26
Russ Coxb15c4242010-12-07 16:15:15 -050027// Server returns a new TLS server side connection
28// using conn as the underlying transport.
aubble34695c42015-08-20 14:26:56 -040029// The configuration config must be non-nil and must include
30// at least one certificate or else set GetCertificate.
Adam Langley6e0842d2009-11-21 15:53:03 -080031func Server(conn net.Conn, config *Config) *Conn {
Russ Cox72d93222010-04-26 22:19:04 -070032 return &Conn{conn: conn, config: config}
Adam Langley6e0842d2009-11-21 15:53:03 -080033}
34
Russ Coxb15c4242010-12-07 16:15:15 -050035// Client returns a new TLS client side connection
36// using conn as the underlying transport.
Brad Fitzpatrick19fe9a22014-06-03 18:11:17 +100037// The config cannot be nil: users must set either ServerName or
Adam Langley80692a32014-02-19 11:17:09 -050038// InsecureSkipVerify in the config.
Adam Langley6e0842d2009-11-21 15:53:03 -080039func Client(conn net.Conn, config *Config) *Conn {
Russ Cox72d93222010-04-26 22:19:04 -070040 return &Conn{conn: conn, config: config, isClient: true}
Adam Langley6e0842d2009-11-21 15:53:03 -080041}
42
Adam Langley005686f2012-02-03 15:08:53 -050043// A listener implements a network listener (net.Listener) for TLS connections.
44type listener struct {
45 net.Listener
46 config *Config
Adam Langley950f2632009-11-05 16:43:29 -080047}
48
Russ Coxb15c4242010-12-07 16:15:15 -050049// Accept waits for and returns the next incoming TLS connection.
Brad Fitzpatrick351c15f2016-02-28 15:52:49 -080050// The returned connection is of type *Conn.
51func (l *listener) Accept() (net.Conn, error) {
52 c, err := l.Listener.Accept()
Adam Langley950f2632009-11-05 16:43:29 -080053 if err != nil {
Brad Fitzpatrick351c15f2016-02-28 15:52:49 -080054 return nil, err
Adam Langley950f2632009-11-05 16:43:29 -080055 }
Brad Fitzpatrick351c15f2016-02-28 15:52:49 -080056 return Server(c, l.config), nil
Adam Langley950f2632009-11-05 16:43:29 -080057}
58
Adam Langley950f2632009-11-05 16:43:29 -080059// NewListener creates a Listener which accepts connections from an inner
60// Listener and wraps each connection with Server.
aubble34695c42015-08-20 14:26:56 -040061// The configuration config must be non-nil and must include
62// at least one certificate or else set GetCertificate.
Adam Langley005686f2012-02-03 15:08:53 -050063func NewListener(inner net.Listener, config *Config) net.Listener {
64 l := new(listener)
65 l.Listener = inner
Robert Griesemer5a1d3322009-12-15 15:33:31 -080066 l.config = config
Adam Langley005686f2012-02-03 15:08:53 -050067 return l
Adam Langley950f2632009-11-05 16:43:29 -080068}
Russ Cox99d258a2010-04-05 14:38:02 -070069
Russ Coxb15c4242010-12-07 16:15:15 -050070// Listen creates a TLS listener accepting connections on the
71// given network address using net.Listen.
aubble34695c42015-08-20 14:26:56 -040072// The configuration config must be non-nil and must include
73// at least one certificate or else set GetCertificate.
Adam Langley005686f2012-02-03 15:08:53 -050074func Listen(network, laddr string, config *Config) (net.Listener, error) {
aubblebfa01612015-08-20 14:31:15 -040075 if config == nil || (len(config.Certificates) == 0 && config.GetCertificate == nil) {
76 return nil, errors.New("tls: neither Certificates nor GetCertificate set in Config")
Russ Cox72d93222010-04-26 22:19:04 -070077 }
Russ Cox99d258a2010-04-05 14:38:02 -070078 l, err := net.Listen(network, laddr)
79 if err != nil {
80 return nil, err
81 }
Russ Cox72d93222010-04-26 22:19:04 -070082 return NewListener(l, config), nil
Russ Cox99d258a2010-04-05 14:38:02 -070083}
84
Adam Langley1f8b2a62014-02-28 09:40:12 -050085type timeoutError struct{}
86
87func (timeoutError) Error() string { return "tls: DialWithDialer timed out" }
88func (timeoutError) Timeout() bool { return true }
89func (timeoutError) Temporary() bool { return true }
90
91// DialWithDialer connects to the given network address using dialer.Dial and
92// then initiates a TLS handshake, returning the resulting TLS connection. Any
93// timeout or deadline given in the dialer apply to connection and TLS
94// handshake as a whole.
95//
96// DialWithDialer interprets a nil configuration as equivalent to the zero
97// configuration; see the documentation of Config for the defaults.
98func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
99 // We want the Timeout and Deadline values from dialer to cover the
100 // whole process: TCP connection and TLS handshake. This means that we
101 // also need to start our own timers now.
102 timeout := dialer.Timeout
103
104 if !dialer.Deadline.IsZero() {
105 deadlineTimeout := dialer.Deadline.Sub(time.Now())
106 if timeout == 0 || deadlineTimeout < timeout {
107 timeout = deadlineTimeout
108 }
109 }
110
111 var errChannel chan error
112
113 if timeout != 0 {
114 errChannel = make(chan error, 2)
115 time.AfterFunc(timeout, func() {
116 errChannel <- timeoutError{}
117 })
118 }
119
120 rawConn, err := dialer.Dial(network, addr)
Russ Cox99d258a2010-04-05 14:38:02 -0700121 if err != nil {
122 return nil, err
123 }
Adam Langley836529a2010-11-05 09:54:56 -0400124
Adam Langley1f8b2a62014-02-28 09:40:12 -0500125 colonPos := strings.LastIndex(addr, ":")
Adam Langley836529a2010-11-05 09:54:56 -0400126 if colonPos == -1 {
Adam Langley1f8b2a62014-02-28 09:40:12 -0500127 colonPos = len(addr)
Adam Langley836529a2010-11-05 09:54:56 -0400128 }
Adam Langley1f8b2a62014-02-28 09:40:12 -0500129 hostname := addr[:colonPos]
Adam Langley836529a2010-11-05 09:54:56 -0400130
Russ Coxb15c4242010-12-07 16:15:15 -0500131 if config == nil {
132 config = defaultConfig()
Adam Langley6989f6e2010-09-20 10:32:08 -0400133 }
Mikkel Krautza324a5a2012-03-07 13:12:35 -0500134 // If no ServerName is set, infer the ServerName
135 // from the hostname we're connecting to.
136 if config.ServerName == "" {
Russ Coxb15c4242010-12-07 16:15:15 -0500137 // Make a copy to avoid polluting argument or default.
138 c := *config
139 c.ServerName = hostname
140 config = &c
141 }
Adam Langley1f8b2a62014-02-28 09:40:12 -0500142
143 conn := Client(rawConn, config)
144
145 if timeout == 0 {
146 err = conn.Handshake()
147 } else {
148 go func() {
149 errChannel <- conn.Handshake()
150 }()
151
152 err = <-errChannel
153 }
154
155 if err != nil {
156 rawConn.Close()
Russ Coxb15c4242010-12-07 16:15:15 -0500157 return nil, err
158 }
Adam Langley1f8b2a62014-02-28 09:40:12 -0500159
Russ Coxb15c4242010-12-07 16:15:15 -0500160 return conn, nil
Russ Cox99d258a2010-04-05 14:38:02 -0700161}
Adam Langleyfc23def2010-07-02 13:00:18 -0400162
Adam Langley1f8b2a62014-02-28 09:40:12 -0500163// Dial connects to the given network address using net.Dial
164// and then initiates a TLS handshake, returning the resulting
165// TLS connection.
166// Dial interprets a nil configuration as equivalent to
167// the zero configuration; see the documentation of Config
168// for the defaults.
169func Dial(network, addr string, config *Config) (*Conn, error) {
170 return DialWithDialer(new(net.Dialer), network, addr, config)
171}
172
Adam Langleyf6e2eab2010-10-11 10:39:56 -0400173// LoadX509KeyPair reads and parses a public/private key pair from a pair of
Adam Langleyb203f882016-01-19 08:27:10 -0800174// files. The files must contain PEM encoded data. On successful return,
175// Certificate.Leaf will be nil because the parsed form of the certificate is
176// not retained.
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800177func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) {
Adam Langleyfc23def2010-07-02 13:00:18 -0400178 certPEMBlock, err := ioutil.ReadFile(certFile)
179 if err != nil {
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800180 return Certificate{}, err
Adam Langleyfc23def2010-07-02 13:00:18 -0400181 }
Brad Fitzpatrickcc408702011-04-04 08:32:59 -0700182 keyPEMBlock, err := ioutil.ReadFile(keyFile)
183 if err != nil {
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800184 return Certificate{}, err
Brad Fitzpatrickcc408702011-04-04 08:32:59 -0700185 }
186 return X509KeyPair(certPEMBlock, keyPEMBlock)
187}
Adam Langleyfc23def2010-07-02 13:00:18 -0400188
Brad Fitzpatrickcc408702011-04-04 08:32:59 -0700189// X509KeyPair parses a public/private key pair from a pair of
Adam Langleyb203f882016-01-19 08:27:10 -0800190// PEM encoded data. On successful return, Certificate.Leaf will be nil because
191// the parsed form of the certificate is not retained.
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800192func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800193 fail := func(err error) (Certificate, error) { return Certificate{}, err }
Adam Langleybe160012015-08-30 10:23:30 -0700194
195 var cert Certificate
196 var skippedBlockTypes []string
Adam Langley5626bd92011-02-05 13:54:25 -0500197 for {
Adam Langleybe160012015-08-30 10:23:30 -0700198 var certDERBlock *pem.Block
Adam Langley5626bd92011-02-05 13:54:25 -0500199 certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
200 if certDERBlock == nil {
201 break
202 }
203 if certDERBlock.Type == "CERTIFICATE" {
204 cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
Adam Langleybe160012015-08-30 10:23:30 -0700205 } else {
206 skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type)
Adam Langley5626bd92011-02-05 13:54:25 -0500207 }
208 }
209
210 if len(cert.Certificate) == 0 {
Adam Langleybe160012015-08-30 10:23:30 -0700211 if len(skippedBlockTypes) == 0 {
212 return fail(errors.New("crypto/tls: failed to find any PEM data in certificate input"))
Adam Langleybe160012015-08-30 10:23:30 -0700213 }
Emmanuel Odekef0711b92016-03-14 03:35:13 -0600214 if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
215 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"))
216 }
217 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))
Adam Langleyfc23def2010-07-02 13:00:18 -0400218 }
219
Adam Langleybe160012015-08-30 10:23:30 -0700220 skippedBlockTypes = skippedBlockTypes[:0]
Adam Langleyecc04b82012-09-13 11:00:16 -0400221 var keyDERBlock *pem.Block
222 for {
223 keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
224 if keyDERBlock == nil {
Adam Langleybe160012015-08-30 10:23:30 -0700225 if len(skippedBlockTypes) == 0 {
226 return fail(errors.New("crypto/tls: failed to find any PEM data in key input"))
Adam Langleybe160012015-08-30 10:23:30 -0700227 }
Emmanuel Odekef0711b92016-03-14 03:35:13 -0600228 if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
229 return fail(errors.New("crypto/tls: found a certificate rather than a key in the PEM for the private key"))
230 }
231 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))
Adam Langleyecc04b82012-09-13 11:00:16 -0400232 }
Brad Fitzpatrick444b7b52012-12-01 11:02:08 -0800233 if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
Adam Langleyecc04b82012-09-13 11:00:16 -0400234 break
235 }
Adam Langleybe160012015-08-30 10:23:30 -0700236 skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
Adam Langleyfc23def2010-07-02 13:00:18 -0400237 }
238
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800239 var err error
Joel Singaaf3b712012-11-16 19:33:59 +1100240 cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
241 if err != nil {
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800242 return fail(err)
Adam Langleyfc23def2010-07-02 13:00:18 -0400243 }
244
Adam Langleyfc23def2010-07-02 13:00:18 -0400245 // We don't need to parse the public key for TLS, but we so do anyway
246 // to check that it looks sane and matches the private key.
Adam Langley5626bd92011-02-05 13:54:25 -0500247 x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
Adam Langleyfc23def2010-07-02 13:00:18 -0400248 if err != nil {
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800249 return fail(err)
Adam Langleyfc23def2010-07-02 13:00:18 -0400250 }
251
Joel Singaaf3b712012-11-16 19:33:59 +1100252 switch pub := x509Cert.PublicKey.(type) {
253 case *rsa.PublicKey:
254 priv, ok := cert.PrivateKey.(*rsa.PrivateKey)
255 if !ok {
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800256 return fail(errors.New("crypto/tls: private key type does not match public key type"))
Joel Singaaf3b712012-11-16 19:33:59 +1100257 }
258 if pub.N.Cmp(priv.N) != 0 {
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800259 return fail(errors.New("crypto/tls: private key does not match public key"))
Joel Singaaf3b712012-11-16 19:33:59 +1100260 }
261 case *ecdsa.PublicKey:
262 priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
263 if !ok {
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800264 return fail(errors.New("crypto/tls: private key type does not match public key type"))
Joel Singaaf3b712012-11-16 19:33:59 +1100265 }
266 if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800267 return fail(errors.New("crypto/tls: private key does not match public key"))
Joel Singaaf3b712012-11-16 19:33:59 +1100268 }
269 default:
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800270 return fail(errors.New("crypto/tls: unknown public key algorithm"))
Adam Langleyfc23def2010-07-02 13:00:18 -0400271 }
272
Brad Fitzpatrick552080c2015-01-13 11:34:46 -0800273 return cert, nil
Adam Langleyfc23def2010-07-02 13:00:18 -0400274}
Joel Singaaf3b712012-11-16 19:33:59 +1100275
276// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
277// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
278// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
279func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
280 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
281 return key, nil
282 }
283 if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
284 switch key := key.(type) {
285 case *rsa.PrivateKey, *ecdsa.PrivateKey:
286 return key, nil
287 default:
288 return nil, errors.New("crypto/tls: found unknown private key type in PKCS#8 wrapping")
289 }
290 }
291 if key, err := x509.ParseECPrivateKey(der); err == nil {
292 return key, nil
293 }
294
295 return nil, errors.New("crypto/tls: failed to parse private key")
296}