Source file src/pkg/crypto/tls/tls.go
1
2
3
4
5
6
7
8
9
10
11 package tls
12
13
14
15
16
17
18 import (
19 "bytes"
20 "crypto"
21 "crypto/ecdsa"
22 "crypto/ed25519"
23 "crypto/rsa"
24 "crypto/x509"
25 "encoding/pem"
26 "errors"
27 "fmt"
28 "io/ioutil"
29 "net"
30 "strings"
31 "time"
32 )
33
34
35
36
37
38 func Server(conn net.Conn, config *Config) *Conn {
39 return &Conn{conn: conn, config: config}
40 }
41
42
43
44
45
46 func Client(conn net.Conn, config *Config) *Conn {
47 return &Conn{conn: conn, config: config, isClient: true}
48 }
49
50
51 type listener struct {
52 net.Listener
53 config *Config
54 }
55
56
57
58 func (l *listener) Accept() (net.Conn, error) {
59 c, err := l.Listener.Accept()
60 if err != nil {
61 return nil, err
62 }
63 return Server(c, l.config), nil
64 }
65
66
67
68
69
70 func NewListener(inner net.Listener, config *Config) net.Listener {
71 l := new(listener)
72 l.Listener = inner
73 l.config = config
74 return l
75 }
76
77
78
79
80
81 func Listen(network, laddr string, config *Config) (net.Listener, error) {
82 if config == nil || (len(config.Certificates) == 0 && config.GetCertificate == nil) {
83 return nil, errors.New("tls: neither Certificates nor GetCertificate set in Config")
84 }
85 l, err := net.Listen(network, laddr)
86 if err != nil {
87 return nil, err
88 }
89 return NewListener(l, config), nil
90 }
91
92 type timeoutError struct{}
93
94 func (timeoutError) Error() string { return "tls: DialWithDialer timed out" }
95 func (timeoutError) Timeout() bool { return true }
96 func (timeoutError) Temporary() bool { return true }
97
98
99
100
101
102
103
104
105 func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
106
107
108
109 timeout := dialer.Timeout
110
111 if !dialer.Deadline.IsZero() {
112 deadlineTimeout := time.Until(dialer.Deadline)
113 if timeout == 0 || deadlineTimeout < timeout {
114 timeout = deadlineTimeout
115 }
116 }
117
118 var errChannel chan error
119
120 if timeout != 0 {
121 errChannel = make(chan error, 2)
122 time.AfterFunc(timeout, func() {
123 errChannel <- timeoutError{}
124 })
125 }
126
127 rawConn, err := dialer.Dial(network, addr)
128 if err != nil {
129 return nil, err
130 }
131
132 colonPos := strings.LastIndex(addr, ":")
133 if colonPos == -1 {
134 colonPos = len(addr)
135 }
136 hostname := addr[:colonPos]
137
138 if config == nil {
139 config = defaultConfig()
140 }
141
142
143 if config.ServerName == "" {
144
145 c := config.Clone()
146 c.ServerName = hostname
147 config = c
148 }
149
150 conn := Client(rawConn, config)
151
152 if timeout == 0 {
153 err = conn.Handshake()
154 } else {
155 go func() {
156 errChannel <- conn.Handshake()
157 }()
158
159 err = <-errChannel
160 }
161
162 if err != nil {
163 rawConn.Close()
164 return nil, err
165 }
166
167 return conn, nil
168 }
169
170
171
172
173
174
175
176 func Dial(network, addr string, config *Config) (*Conn, error) {
177 return DialWithDialer(new(net.Dialer), network, addr, config)
178 }
179
180
181
182
183
184
185 func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) {
186 certPEMBlock, err := ioutil.ReadFile(certFile)
187 if err != nil {
188 return Certificate{}, err
189 }
190 keyPEMBlock, err := ioutil.ReadFile(keyFile)
191 if err != nil {
192 return Certificate{}, err
193 }
194 return X509KeyPair(certPEMBlock, keyPEMBlock)
195 }
196
197
198
199
200 func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
201 fail := func(err error) (Certificate, error) { return Certificate{}, err }
202
203 var cert Certificate
204 var skippedBlockTypes []string
205 for {
206 var certDERBlock *pem.Block
207 certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
208 if certDERBlock == nil {
209 break
210 }
211 if certDERBlock.Type == "CERTIFICATE" {
212 cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
213 } else {
214 skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type)
215 }
216 }
217
218 if len(cert.Certificate) == 0 {
219 if len(skippedBlockTypes) == 0 {
220 return fail(errors.New("tls: failed to find any PEM data in certificate input"))
221 }
222 if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
223 return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched"))
224 }
225 return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
226 }
227
228 skippedBlockTypes = skippedBlockTypes[:0]
229 var keyDERBlock *pem.Block
230 for {
231 keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
232 if keyDERBlock == nil {
233 if len(skippedBlockTypes) == 0 {
234 return fail(errors.New("tls: failed to find any PEM data in key input"))
235 }
236 if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
237 return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key"))
238 }
239 return fail(fmt.Errorf("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))
240 }
241 if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
242 break
243 }
244 skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
245 }
246
247
248
249 x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
250 if err != nil {
251 return fail(err)
252 }
253
254 cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
255 if err != nil {
256 return fail(err)
257 }
258
259 switch pub := x509Cert.PublicKey.(type) {
260 case *rsa.PublicKey:
261 priv, ok := cert.PrivateKey.(*rsa.PrivateKey)
262 if !ok {
263 return fail(errors.New("tls: private key type does not match public key type"))
264 }
265 if pub.N.Cmp(priv.N) != 0 {
266 return fail(errors.New("tls: private key does not match public key"))
267 }
268 case *ecdsa.PublicKey:
269 priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
270 if !ok {
271 return fail(errors.New("tls: private key type does not match public key type"))
272 }
273 if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
274 return fail(errors.New("tls: private key does not match public key"))
275 }
276 case ed25519.PublicKey:
277 priv, ok := cert.PrivateKey.(ed25519.PrivateKey)
278 if !ok {
279 return fail(errors.New("tls: private key type does not match public key type"))
280 }
281 if !bytes.Equal(priv.Public().(ed25519.PublicKey), pub) {
282 return fail(errors.New("tls: private key does not match public key"))
283 }
284 default:
285 return fail(errors.New("tls: unknown public key algorithm"))
286 }
287
288 return cert, nil
289 }
290
291
292
293
294 func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
295 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
296 return key, nil
297 }
298 if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
299 switch key := key.(type) {
300 case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
301 return key, nil
302 default:
303 return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping")
304 }
305 }
306 if key, err := x509.ParseECPrivateKey(der); err == nil {
307 return key, nil
308 }
309
310 return nil, errors.New("tls: failed to parse private key")
311 }
312
View as plain text