blob: f4b4c361ee98f6483fdbf31c0b1249fe23ea50da [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001// Copyright 2010 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// TLS low level connection and record layer
6
7package main
8
9import (
10 "bytes"
11 "crypto/cipher"
David Benjamind30a9902014-08-24 01:44:23 -040012 "crypto/ecdsa"
Adam Langley95c29f32014-06-20 12:00:00 -070013 "crypto/subtle"
14 "crypto/x509"
15 "errors"
16 "fmt"
17 "io"
18 "net"
19 "sync"
20 "time"
21)
22
23// A Conn represents a secured connection.
24// It implements the net.Conn interface.
25type Conn struct {
26 // constant
27 conn net.Conn
David Benjamin83c0bc92014-08-04 01:23:53 -040028 isDTLS bool
Adam Langley95c29f32014-06-20 12:00:00 -070029 isClient bool
30
31 // constant after handshake; protected by handshakeMutex
Adam Langley75712922014-10-10 16:23:43 -070032 handshakeMutex sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
33 handshakeErr error // error resulting from handshake
34 vers uint16 // TLS version
35 haveVers bool // version has been negotiated
36 config *Config // configuration passed to constructor
37 handshakeComplete bool
38 didResume bool // whether this connection was a session resumption
39 extendedMasterSecret bool // whether this session used an extended master secret
40 cipherSuite uint16
41 ocspResponse []byte // stapled OCSP response
42 peerCertificates []*x509.Certificate
Adam Langley95c29f32014-06-20 12:00:00 -070043 // verifiedChains contains the certificate chains that we built, as
44 // opposed to the ones presented by the server.
45 verifiedChains [][]*x509.Certificate
46 // serverName contains the server name indicated by the client, if any.
47 serverName string
48
49 clientProtocol string
50 clientProtocolFallback bool
David Benjaminfc7b0862014-09-06 13:21:53 -040051 usedALPN bool
Adam Langley95c29f32014-06-20 12:00:00 -070052
Adam Langley2ae77d22014-10-28 17:29:33 -070053 // verify_data values for the renegotiation extension.
54 clientVerify []byte
55 serverVerify []byte
56
David Benjamind30a9902014-08-24 01:44:23 -040057 channelID *ecdsa.PublicKey
58
Adam Langley95c29f32014-06-20 12:00:00 -070059 // input/output
60 in, out halfConn // in.Mutex < out.Mutex
61 rawInput *block // raw input, right off the wire
David Benjamin83c0bc92014-08-04 01:23:53 -040062 input *block // application record waiting to be read
63 hand bytes.Buffer // handshake record waiting to be read
64
65 // DTLS state
66 sendHandshakeSeq uint16
67 recvHandshakeSeq uint16
68 handMsg []byte // pending assembled handshake message
69 handMsgLen int // handshake message length, not including the header
Adam Langley95c29f32014-06-20 12:00:00 -070070
71 tmp [16]byte
72}
73
David Benjamin5e961c12014-11-07 01:48:35 -050074func (c *Conn) init() {
75 c.in.isDTLS = c.isDTLS
76 c.out.isDTLS = c.isDTLS
77 c.in.config = c.config
78 c.out.config = c.config
79}
80
Adam Langley95c29f32014-06-20 12:00:00 -070081// Access to net.Conn methods.
82// Cannot just embed net.Conn because that would
83// export the struct field too.
84
85// LocalAddr returns the local network address.
86func (c *Conn) LocalAddr() net.Addr {
87 return c.conn.LocalAddr()
88}
89
90// RemoteAddr returns the remote network address.
91func (c *Conn) RemoteAddr() net.Addr {
92 return c.conn.RemoteAddr()
93}
94
95// SetDeadline sets the read and write deadlines associated with the connection.
96// A zero value for t means Read and Write will not time out.
97// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
98func (c *Conn) SetDeadline(t time.Time) error {
99 return c.conn.SetDeadline(t)
100}
101
102// SetReadDeadline sets the read deadline on the underlying connection.
103// A zero value for t means Read will not time out.
104func (c *Conn) SetReadDeadline(t time.Time) error {
105 return c.conn.SetReadDeadline(t)
106}
107
108// SetWriteDeadline sets the write deadline on the underlying conneciton.
109// A zero value for t means Write will not time out.
110// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
111func (c *Conn) SetWriteDeadline(t time.Time) error {
112 return c.conn.SetWriteDeadline(t)
113}
114
115// A halfConn represents one direction of the record layer
116// connection, either sending or receiving.
117type halfConn struct {
118 sync.Mutex
119
David Benjamin83c0bc92014-08-04 01:23:53 -0400120 err error // first permanent error
121 version uint16 // protocol version
122 isDTLS bool
Adam Langley95c29f32014-06-20 12:00:00 -0700123 cipher interface{} // cipher algorithm
124 mac macFunction
125 seq [8]byte // 64-bit sequence number
126 bfree *block // list of free blocks
127
128 nextCipher interface{} // next encryption state
129 nextMac macFunction // next MAC algorithm
130
131 // used to save allocating a new buffer for each MAC.
132 inDigestBuf, outDigestBuf []byte
Adam Langley80842bd2014-06-20 12:00:00 -0700133
134 config *Config
Adam Langley95c29f32014-06-20 12:00:00 -0700135}
136
137func (hc *halfConn) setErrorLocked(err error) error {
138 hc.err = err
139 return err
140}
141
142func (hc *halfConn) error() error {
Adam Langley2ae77d22014-10-28 17:29:33 -0700143 // This should be locked, but I've removed it for the renegotiation
144 // tests since we don't concurrently read and write the same tls.Conn
145 // in any case during testing.
Adam Langley95c29f32014-06-20 12:00:00 -0700146 err := hc.err
Adam Langley95c29f32014-06-20 12:00:00 -0700147 return err
148}
149
150// prepareCipherSpec sets the encryption and MAC states
151// that a subsequent changeCipherSpec will use.
152func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) {
153 hc.version = version
154 hc.nextCipher = cipher
155 hc.nextMac = mac
156}
157
158// changeCipherSpec changes the encryption and MAC states
159// to the ones previously passed to prepareCipherSpec.
Adam Langley80842bd2014-06-20 12:00:00 -0700160func (hc *halfConn) changeCipherSpec(config *Config) error {
Adam Langley95c29f32014-06-20 12:00:00 -0700161 if hc.nextCipher == nil {
162 return alertInternalError
163 }
164 hc.cipher = hc.nextCipher
165 hc.mac = hc.nextMac
166 hc.nextCipher = nil
167 hc.nextMac = nil
Adam Langley80842bd2014-06-20 12:00:00 -0700168 hc.config = config
David Benjamin83c0bc92014-08-04 01:23:53 -0400169 hc.incEpoch()
Adam Langley95c29f32014-06-20 12:00:00 -0700170 return nil
171}
172
173// incSeq increments the sequence number.
David Benjamin5e961c12014-11-07 01:48:35 -0500174func (hc *halfConn) incSeq(isOutgoing bool) {
David Benjamin83c0bc92014-08-04 01:23:53 -0400175 limit := 0
David Benjamin5e961c12014-11-07 01:48:35 -0500176 increment := uint64(1)
David Benjamin83c0bc92014-08-04 01:23:53 -0400177 if hc.isDTLS {
178 // Increment up to the epoch in DTLS.
179 limit = 2
David Benjamin5e961c12014-11-07 01:48:35 -0500180
181 if isOutgoing && hc.config.Bugs.SequenceNumberIncrement != 0 {
182 increment = hc.config.Bugs.SequenceNumberIncrement
183 }
David Benjamin83c0bc92014-08-04 01:23:53 -0400184 }
185 for i := 7; i >= limit; i-- {
David Benjamin5e961c12014-11-07 01:48:35 -0500186 increment += uint64(hc.seq[i])
187 hc.seq[i] = byte(increment)
188 increment >>= 8
Adam Langley95c29f32014-06-20 12:00:00 -0700189 }
190
191 // Not allowed to let sequence number wrap.
192 // Instead, must renegotiate before it does.
193 // Not likely enough to bother.
David Benjamin5e961c12014-11-07 01:48:35 -0500194 if increment != 0 {
195 panic("TLS: sequence number wraparound")
196 }
Adam Langley95c29f32014-06-20 12:00:00 -0700197}
198
David Benjamin83c0bc92014-08-04 01:23:53 -0400199// incEpoch resets the sequence number. In DTLS, it increments the
200// epoch half of the sequence number.
201func (hc *halfConn) incEpoch() {
202 limit := 0
203 if hc.isDTLS {
204 for i := 1; i >= 0; i-- {
205 hc.seq[i]++
206 if hc.seq[i] != 0 {
207 break
208 }
209 if i == 0 {
210 panic("TLS: epoch number wraparound")
211 }
212 }
213 limit = 2
Adam Langley95c29f32014-06-20 12:00:00 -0700214 }
David Benjamin83c0bc92014-08-04 01:23:53 -0400215 seq := hc.seq[limit:]
216 for i := range seq {
217 seq[i] = 0
218 }
219}
220
221func (hc *halfConn) recordHeaderLen() int {
222 if hc.isDTLS {
223 return dtlsRecordHeaderLen
224 }
225 return tlsRecordHeaderLen
Adam Langley95c29f32014-06-20 12:00:00 -0700226}
227
228// removePadding returns an unpadded slice, in constant time, which is a prefix
229// of the input. It also returns a byte which is equal to 255 if the padding
230// was valid and 0 otherwise. See RFC 2246, section 6.2.3.2
231func removePadding(payload []byte) ([]byte, byte) {
232 if len(payload) < 1 {
233 return payload, 0
234 }
235
236 paddingLen := payload[len(payload)-1]
237 t := uint(len(payload)-1) - uint(paddingLen)
238 // if len(payload) >= (paddingLen - 1) then the MSB of t is zero
239 good := byte(int32(^t) >> 31)
240
241 toCheck := 255 // the maximum possible padding length
242 // The length of the padded data is public, so we can use an if here
243 if toCheck+1 > len(payload) {
244 toCheck = len(payload) - 1
245 }
246
247 for i := 0; i < toCheck; i++ {
248 t := uint(paddingLen) - uint(i)
249 // if i <= paddingLen then the MSB of t is zero
250 mask := byte(int32(^t) >> 31)
251 b := payload[len(payload)-1-i]
252 good &^= mask&paddingLen ^ mask&b
253 }
254
255 // We AND together the bits of good and replicate the result across
256 // all the bits.
257 good &= good << 4
258 good &= good << 2
259 good &= good << 1
260 good = uint8(int8(good) >> 7)
261
262 toRemove := good&paddingLen + 1
263 return payload[:len(payload)-int(toRemove)], good
264}
265
266// removePaddingSSL30 is a replacement for removePadding in the case that the
267// protocol version is SSLv3. In this version, the contents of the padding
268// are random and cannot be checked.
269func removePaddingSSL30(payload []byte) ([]byte, byte) {
270 if len(payload) < 1 {
271 return payload, 0
272 }
273
274 paddingLen := int(payload[len(payload)-1]) + 1
275 if paddingLen > len(payload) {
276 return payload, 0
277 }
278
279 return payload[:len(payload)-paddingLen], 255
280}
281
282func roundUp(a, b int) int {
283 return a + (b-a%b)%b
284}
285
286// cbcMode is an interface for block ciphers using cipher block chaining.
287type cbcMode interface {
288 cipher.BlockMode
289 SetIV([]byte)
290}
291
292// decrypt checks and strips the mac and decrypts the data in b. Returns a
293// success boolean, the number of bytes to skip from the start of the record in
294// order to get the application payload, and an optional alert value.
295func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) {
David Benjamin83c0bc92014-08-04 01:23:53 -0400296 recordHeaderLen := hc.recordHeaderLen()
297
Adam Langley95c29f32014-06-20 12:00:00 -0700298 // pull out payload
299 payload := b.data[recordHeaderLen:]
300
301 macSize := 0
302 if hc.mac != nil {
303 macSize = hc.mac.Size()
304 }
305
306 paddingGood := byte(255)
307 explicitIVLen := 0
308
David Benjamin83c0bc92014-08-04 01:23:53 -0400309 seq := hc.seq[:]
310 if hc.isDTLS {
311 // DTLS sequence numbers are explicit.
312 seq = b.data[3:11]
313 }
314
Adam Langley95c29f32014-06-20 12:00:00 -0700315 // decrypt
316 if hc.cipher != nil {
317 switch c := hc.cipher.(type) {
318 case cipher.Stream:
319 c.XORKeyStream(payload, payload)
320 case cipher.AEAD:
321 explicitIVLen = 8
322 if len(payload) < explicitIVLen {
323 return false, 0, alertBadRecordMAC
324 }
325 nonce := payload[:8]
326 payload = payload[8:]
327
328 var additionalData [13]byte
David Benjamin83c0bc92014-08-04 01:23:53 -0400329 copy(additionalData[:], seq)
Adam Langley95c29f32014-06-20 12:00:00 -0700330 copy(additionalData[8:], b.data[:3])
331 n := len(payload) - c.Overhead()
332 additionalData[11] = byte(n >> 8)
333 additionalData[12] = byte(n)
334 var err error
335 payload, err = c.Open(payload[:0], nonce, payload, additionalData[:])
336 if err != nil {
337 return false, 0, alertBadRecordMAC
338 }
339 b.resize(recordHeaderLen + explicitIVLen + len(payload))
340 case cbcMode:
341 blockSize := c.BlockSize()
David Benjamin83c0bc92014-08-04 01:23:53 -0400342 if hc.version >= VersionTLS11 || hc.isDTLS {
Adam Langley95c29f32014-06-20 12:00:00 -0700343 explicitIVLen = blockSize
344 }
345
346 if len(payload)%blockSize != 0 || len(payload) < roundUp(explicitIVLen+macSize+1, blockSize) {
347 return false, 0, alertBadRecordMAC
348 }
349
350 if explicitIVLen > 0 {
351 c.SetIV(payload[:explicitIVLen])
352 payload = payload[explicitIVLen:]
353 }
354 c.CryptBlocks(payload, payload)
355 if hc.version == VersionSSL30 {
356 payload, paddingGood = removePaddingSSL30(payload)
357 } else {
358 payload, paddingGood = removePadding(payload)
359 }
360 b.resize(recordHeaderLen + explicitIVLen + len(payload))
361
362 // note that we still have a timing side-channel in the
363 // MAC check, below. An attacker can align the record
364 // so that a correct padding will cause one less hash
365 // block to be calculated. Then they can iteratively
366 // decrypt a record by breaking each byte. See
367 // "Password Interception in a SSL/TLS Channel", Brice
368 // Canvel et al.
369 //
370 // However, our behavior matches OpenSSL, so we leak
371 // only as much as they do.
372 default:
373 panic("unknown cipher type")
374 }
375 }
376
377 // check, strip mac
378 if hc.mac != nil {
379 if len(payload) < macSize {
380 return false, 0, alertBadRecordMAC
381 }
382
383 // strip mac off payload, b.data
384 n := len(payload) - macSize
David Benjamin83c0bc92014-08-04 01:23:53 -0400385 b.data[recordHeaderLen-2] = byte(n >> 8)
386 b.data[recordHeaderLen-1] = byte(n)
Adam Langley95c29f32014-06-20 12:00:00 -0700387 b.resize(recordHeaderLen + explicitIVLen + n)
388 remoteMAC := payload[n:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400389 localMAC := hc.mac.MAC(hc.inDigestBuf, seq, b.data[:3], b.data[recordHeaderLen-2:recordHeaderLen], payload[:n])
Adam Langley95c29f32014-06-20 12:00:00 -0700390
391 if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 {
392 return false, 0, alertBadRecordMAC
393 }
394 hc.inDigestBuf = localMAC
395 }
David Benjamin5e961c12014-11-07 01:48:35 -0500396 hc.incSeq(false)
Adam Langley95c29f32014-06-20 12:00:00 -0700397
398 return true, recordHeaderLen + explicitIVLen, 0
399}
400
401// padToBlockSize calculates the needed padding block, if any, for a payload.
402// On exit, prefix aliases payload and extends to the end of the last full
403// block of payload. finalBlock is a fresh slice which contains the contents of
404// any suffix of payload as well as the needed padding to make finalBlock a
405// full block.
Adam Langley80842bd2014-06-20 12:00:00 -0700406func padToBlockSize(payload []byte, blockSize int, config *Config) (prefix, finalBlock []byte) {
Adam Langley95c29f32014-06-20 12:00:00 -0700407 overrun := len(payload) % blockSize
Adam Langley95c29f32014-06-20 12:00:00 -0700408 prefix = payload[:len(payload)-overrun]
Adam Langley80842bd2014-06-20 12:00:00 -0700409
410 paddingLen := blockSize - overrun
411 finalSize := blockSize
412 if config.Bugs.MaxPadding {
413 for paddingLen+blockSize <= 256 {
414 paddingLen += blockSize
415 }
416 finalSize = 256
417 }
418 finalBlock = make([]byte, finalSize)
419 for i := range finalBlock {
Adam Langley95c29f32014-06-20 12:00:00 -0700420 finalBlock[i] = byte(paddingLen - 1)
421 }
Adam Langley80842bd2014-06-20 12:00:00 -0700422 if config.Bugs.PaddingFirstByteBad || config.Bugs.PaddingFirstByteBadIf255 && paddingLen == 256 {
423 finalBlock[overrun] ^= 0xff
424 }
425 copy(finalBlock, payload[len(payload)-overrun:])
Adam Langley95c29f32014-06-20 12:00:00 -0700426 return
427}
428
429// encrypt encrypts and macs the data in b.
430func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
David Benjamin83c0bc92014-08-04 01:23:53 -0400431 recordHeaderLen := hc.recordHeaderLen()
432
Adam Langley95c29f32014-06-20 12:00:00 -0700433 // mac
434 if hc.mac != nil {
David Benjamin83c0bc92014-08-04 01:23:53 -0400435 mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data[:3], b.data[recordHeaderLen-2:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:])
Adam Langley95c29f32014-06-20 12:00:00 -0700436
437 n := len(b.data)
438 b.resize(n + len(mac))
439 copy(b.data[n:], mac)
440 hc.outDigestBuf = mac
441 }
442
443 payload := b.data[recordHeaderLen:]
444
445 // encrypt
446 if hc.cipher != nil {
447 switch c := hc.cipher.(type) {
448 case cipher.Stream:
449 c.XORKeyStream(payload, payload)
450 case cipher.AEAD:
451 payloadLen := len(b.data) - recordHeaderLen - explicitIVLen
452 b.resize(len(b.data) + c.Overhead())
453 nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
454 payload := b.data[recordHeaderLen+explicitIVLen:]
455 payload = payload[:payloadLen]
456
457 var additionalData [13]byte
458 copy(additionalData[:], hc.seq[:])
459 copy(additionalData[8:], b.data[:3])
460 additionalData[11] = byte(payloadLen >> 8)
461 additionalData[12] = byte(payloadLen)
462
463 c.Seal(payload[:0], nonce, payload, additionalData[:])
464 case cbcMode:
465 blockSize := c.BlockSize()
466 if explicitIVLen > 0 {
467 c.SetIV(payload[:explicitIVLen])
468 payload = payload[explicitIVLen:]
469 }
Adam Langley80842bd2014-06-20 12:00:00 -0700470 prefix, finalBlock := padToBlockSize(payload, blockSize, hc.config)
Adam Langley95c29f32014-06-20 12:00:00 -0700471 b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock))
472 c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix)
473 c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock)
474 default:
475 panic("unknown cipher type")
476 }
477 }
478
479 // update length to include MAC and any block padding needed.
480 n := len(b.data) - recordHeaderLen
David Benjamin83c0bc92014-08-04 01:23:53 -0400481 b.data[recordHeaderLen-2] = byte(n >> 8)
482 b.data[recordHeaderLen-1] = byte(n)
David Benjamin5e961c12014-11-07 01:48:35 -0500483 hc.incSeq(true)
Adam Langley95c29f32014-06-20 12:00:00 -0700484
485 return true, 0
486}
487
488// A block is a simple data buffer.
489type block struct {
490 data []byte
491 off int // index for Read
492 link *block
493}
494
495// resize resizes block to be n bytes, growing if necessary.
496func (b *block) resize(n int) {
497 if n > cap(b.data) {
498 b.reserve(n)
499 }
500 b.data = b.data[0:n]
501}
502
503// reserve makes sure that block contains a capacity of at least n bytes.
504func (b *block) reserve(n int) {
505 if cap(b.data) >= n {
506 return
507 }
508 m := cap(b.data)
509 if m == 0 {
510 m = 1024
511 }
512 for m < n {
513 m *= 2
514 }
515 data := make([]byte, len(b.data), m)
516 copy(data, b.data)
517 b.data = data
518}
519
520// readFromUntil reads from r into b until b contains at least n bytes
521// or else returns an error.
522func (b *block) readFromUntil(r io.Reader, n int) error {
523 // quick case
524 if len(b.data) >= n {
525 return nil
526 }
527
528 // read until have enough.
529 b.reserve(n)
530 for {
531 m, err := r.Read(b.data[len(b.data):cap(b.data)])
532 b.data = b.data[0 : len(b.data)+m]
533 if len(b.data) >= n {
534 // TODO(bradfitz,agl): slightly suspicious
535 // that we're throwing away r.Read's err here.
536 break
537 }
538 if err != nil {
539 return err
540 }
541 }
542 return nil
543}
544
545func (b *block) Read(p []byte) (n int, err error) {
546 n = copy(p, b.data[b.off:])
547 b.off += n
548 return
549}
550
551// newBlock allocates a new block, from hc's free list if possible.
552func (hc *halfConn) newBlock() *block {
553 b := hc.bfree
554 if b == nil {
555 return new(block)
556 }
557 hc.bfree = b.link
558 b.link = nil
559 b.resize(0)
560 return b
561}
562
563// freeBlock returns a block to hc's free list.
564// The protocol is such that each side only has a block or two on
565// its free list at a time, so there's no need to worry about
566// trimming the list, etc.
567func (hc *halfConn) freeBlock(b *block) {
568 b.link = hc.bfree
569 hc.bfree = b
570}
571
572// splitBlock splits a block after the first n bytes,
573// returning a block with those n bytes and a
574// block with the remainder. the latter may be nil.
575func (hc *halfConn) splitBlock(b *block, n int) (*block, *block) {
576 if len(b.data) <= n {
577 return b, nil
578 }
579 bb := hc.newBlock()
580 bb.resize(len(b.data) - n)
581 copy(bb.data, b.data[n:])
582 b.data = b.data[0:n]
583 return b, bb
584}
585
David Benjamin83c0bc92014-08-04 01:23:53 -0400586func (c *Conn) doReadRecord(want recordType) (recordType, *block, error) {
587 if c.isDTLS {
588 return c.dtlsDoReadRecord(want)
589 }
590
591 recordHeaderLen := tlsRecordHeaderLen
592
593 if c.rawInput == nil {
594 c.rawInput = c.in.newBlock()
595 }
596 b := c.rawInput
597
598 // Read header, payload.
599 if err := b.readFromUntil(c.conn, recordHeaderLen); err != nil {
600 // RFC suggests that EOF without an alertCloseNotify is
601 // an error, but popular web sites seem to do this,
602 // so we can't make it an error.
603 // if err == io.EOF {
604 // err = io.ErrUnexpectedEOF
605 // }
606 if e, ok := err.(net.Error); !ok || !e.Temporary() {
607 c.in.setErrorLocked(err)
608 }
609 return 0, nil, err
610 }
611 typ := recordType(b.data[0])
612
613 // No valid TLS record has a type of 0x80, however SSLv2 handshakes
614 // start with a uint16 length where the MSB is set and the first record
615 // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
616 // an SSLv2 client.
617 if want == recordTypeHandshake && typ == 0x80 {
618 c.sendAlert(alertProtocolVersion)
619 return 0, nil, c.in.setErrorLocked(errors.New("tls: unsupported SSLv2 handshake received"))
620 }
621
622 vers := uint16(b.data[1])<<8 | uint16(b.data[2])
623 n := int(b.data[3])<<8 | int(b.data[4])
624 if c.haveVers && vers != c.vers {
625 c.sendAlert(alertProtocolVersion)
626 return 0, nil, c.in.setErrorLocked(fmt.Errorf("tls: received record with version %x when expecting version %x", vers, c.vers))
627 }
628 if n > maxCiphertext {
629 c.sendAlert(alertRecordOverflow)
630 return 0, nil, c.in.setErrorLocked(fmt.Errorf("tls: oversized record received with length %d", n))
631 }
632 if !c.haveVers {
633 // First message, be extra suspicious:
634 // this might not be a TLS client.
635 // Bail out before reading a full 'body', if possible.
636 // The current max version is 3.1.
637 // If the version is >= 16.0, it's probably not real.
638 // Similarly, a clientHello message encodes in
639 // well under a kilobyte. If the length is >= 12 kB,
640 // it's probably not real.
641 if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 || n >= 0x3000 {
642 c.sendAlert(alertUnexpectedMessage)
643 return 0, nil, c.in.setErrorLocked(fmt.Errorf("tls: first record does not look like a TLS handshake"))
644 }
645 }
646 if err := b.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
647 if err == io.EOF {
648 err = io.ErrUnexpectedEOF
649 }
650 if e, ok := err.(net.Error); !ok || !e.Temporary() {
651 c.in.setErrorLocked(err)
652 }
653 return 0, nil, err
654 }
655
656 // Process message.
657 b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n)
658 ok, off, err := c.in.decrypt(b)
659 if !ok {
660 c.in.setErrorLocked(c.sendAlert(err))
661 }
662 b.off = off
663 return typ, b, nil
664}
665
Adam Langley95c29f32014-06-20 12:00:00 -0700666// readRecord reads the next TLS record from the connection
667// and updates the record layer state.
668// c.in.Mutex <= L; c.input == nil.
669func (c *Conn) readRecord(want recordType) error {
670 // Caller must be in sync with connection:
671 // handshake data if handshake not yet completed,
Adam Langley2ae77d22014-10-28 17:29:33 -0700672 // else application data.
Adam Langley95c29f32014-06-20 12:00:00 -0700673 switch want {
674 default:
675 c.sendAlert(alertInternalError)
676 return c.in.setErrorLocked(errors.New("tls: unknown record type requested"))
677 case recordTypeHandshake, recordTypeChangeCipherSpec:
678 if c.handshakeComplete {
679 c.sendAlert(alertInternalError)
680 return c.in.setErrorLocked(errors.New("tls: handshake or ChangeCipherSpec requested after handshake complete"))
681 }
682 case recordTypeApplicationData:
David Benjamine58c4f52014-08-24 03:47:07 -0400683 if !c.handshakeComplete && !c.config.Bugs.ExpectFalseStart {
Adam Langley95c29f32014-06-20 12:00:00 -0700684 c.sendAlert(alertInternalError)
685 return c.in.setErrorLocked(errors.New("tls: application data record requested before handshake complete"))
686 }
687 }
688
689Again:
David Benjamin83c0bc92014-08-04 01:23:53 -0400690 typ, b, err := c.doReadRecord(want)
691 if err != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700692 return err
693 }
Adam Langley95c29f32014-06-20 12:00:00 -0700694 data := b.data[b.off:]
695 if len(data) > maxPlaintext {
696 err := c.sendAlert(alertRecordOverflow)
697 c.in.freeBlock(b)
698 return c.in.setErrorLocked(err)
699 }
700
701 switch typ {
702 default:
703 c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
704
705 case recordTypeAlert:
706 if len(data) != 2 {
707 c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
708 break
709 }
710 if alert(data[1]) == alertCloseNotify {
711 c.in.setErrorLocked(io.EOF)
712 break
713 }
714 switch data[0] {
715 case alertLevelWarning:
716 // drop on the floor
717 c.in.freeBlock(b)
718 goto Again
719 case alertLevelError:
720 c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
721 default:
722 c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
723 }
724
725 case recordTypeChangeCipherSpec:
726 if typ != want || len(data) != 1 || data[0] != 1 {
727 c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
728 break
729 }
Adam Langley80842bd2014-06-20 12:00:00 -0700730 err := c.in.changeCipherSpec(c.config)
Adam Langley95c29f32014-06-20 12:00:00 -0700731 if err != nil {
732 c.in.setErrorLocked(c.sendAlert(err.(alert)))
733 }
734
735 case recordTypeApplicationData:
736 if typ != want {
737 c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
738 break
739 }
740 c.input = b
741 b = nil
742
743 case recordTypeHandshake:
744 // TODO(rsc): Should at least pick off connection close.
745 if typ != want {
Adam Langley2ae77d22014-10-28 17:29:33 -0700746 // A client might need to process a HelloRequest from
747 // the server, thus receiving a handshake message when
748 // application data is expected is ok.
749 if !c.isClient {
750 return c.in.setErrorLocked(c.sendAlert(alertNoRenegotiation))
751 }
Adam Langley95c29f32014-06-20 12:00:00 -0700752 }
753 c.hand.Write(data)
754 }
755
756 if b != nil {
757 c.in.freeBlock(b)
758 }
759 return c.in.err
760}
761
762// sendAlert sends a TLS alert message.
763// c.out.Mutex <= L.
764func (c *Conn) sendAlertLocked(err alert) error {
765 switch err {
766 case alertNoRenegotiation, alertCloseNotify:
767 c.tmp[0] = alertLevelWarning
768 default:
769 c.tmp[0] = alertLevelError
770 }
771 c.tmp[1] = byte(err)
Alex Chernyakhovsky4cd8c432014-11-01 19:39:08 -0400772 if c.config.Bugs.FragmentAlert {
773 c.writeRecord(recordTypeAlert, c.tmp[0:1])
774 c.writeRecord(recordTypeAlert, c.tmp[1:2])
775 } else {
776 c.writeRecord(recordTypeAlert, c.tmp[0:2])
777 }
Adam Langley95c29f32014-06-20 12:00:00 -0700778 // closeNotify is a special case in that it isn't an error:
779 if err != alertCloseNotify {
780 return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
781 }
782 return nil
783}
784
785// sendAlert sends a TLS alert message.
786// L < c.out.Mutex.
787func (c *Conn) sendAlert(err alert) error {
788 c.out.Lock()
789 defer c.out.Unlock()
790 return c.sendAlertLocked(err)
791}
792
David Benjamind86c7672014-08-02 04:07:12 -0400793// writeV2Record writes a record for a V2ClientHello.
794func (c *Conn) writeV2Record(data []byte) (n int, err error) {
795 record := make([]byte, 2+len(data))
796 record[0] = uint8(len(data)>>8) | 0x80
797 record[1] = uint8(len(data))
798 copy(record[2:], data)
799 return c.conn.Write(record)
800}
801
Adam Langley95c29f32014-06-20 12:00:00 -0700802// writeRecord writes a TLS record with the given type and payload
803// to the connection and updates the record layer state.
804// c.out.Mutex <= L.
805func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
David Benjamin83c0bc92014-08-04 01:23:53 -0400806 if c.isDTLS {
807 return c.dtlsWriteRecord(typ, data)
808 }
809
810 recordHeaderLen := tlsRecordHeaderLen
Adam Langley95c29f32014-06-20 12:00:00 -0700811 b := c.out.newBlock()
David Benjamin98214542014-08-07 18:02:39 -0400812 first := true
813 isClientHello := typ == recordTypeHandshake && len(data) > 0 && data[0] == typeClientHello
Adam Langley95c29f32014-06-20 12:00:00 -0700814 for len(data) > 0 {
815 m := len(data)
816 if m > maxPlaintext {
817 m = maxPlaintext
818 }
David Benjamin43ec06f2014-08-05 02:28:57 -0400819 if typ == recordTypeHandshake && c.config.Bugs.MaxHandshakeRecordLength > 0 && m > c.config.Bugs.MaxHandshakeRecordLength {
820 m = c.config.Bugs.MaxHandshakeRecordLength
David Benjamin98214542014-08-07 18:02:39 -0400821 // By default, do not fragment the client_version or
822 // server_version, which are located in the first 6
823 // bytes.
824 if first && isClientHello && !c.config.Bugs.FragmentClientVersion && m < 6 {
825 m = 6
826 }
David Benjamin43ec06f2014-08-05 02:28:57 -0400827 }
Adam Langley95c29f32014-06-20 12:00:00 -0700828 explicitIVLen := 0
829 explicitIVIsSeq := false
David Benjamin98214542014-08-07 18:02:39 -0400830 first = false
Adam Langley95c29f32014-06-20 12:00:00 -0700831
832 var cbc cbcMode
833 if c.out.version >= VersionTLS11 {
834 var ok bool
835 if cbc, ok = c.out.cipher.(cbcMode); ok {
836 explicitIVLen = cbc.BlockSize()
837 }
838 }
839 if explicitIVLen == 0 {
840 if _, ok := c.out.cipher.(cipher.AEAD); ok {
841 explicitIVLen = 8
842 // The AES-GCM construction in TLS has an
843 // explicit nonce so that the nonce can be
844 // random. However, the nonce is only 8 bytes
845 // which is too small for a secure, random
846 // nonce. Therefore we use the sequence number
847 // as the nonce.
848 explicitIVIsSeq = true
849 }
850 }
851 b.resize(recordHeaderLen + explicitIVLen + m)
852 b.data[0] = byte(typ)
853 vers := c.vers
854 if vers == 0 {
855 // Some TLS servers fail if the record version is
856 // greater than TLS 1.0 for the initial ClientHello.
857 vers = VersionTLS10
858 }
859 b.data[1] = byte(vers >> 8)
860 b.data[2] = byte(vers)
861 b.data[3] = byte(m >> 8)
862 b.data[4] = byte(m)
863 if explicitIVLen > 0 {
864 explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
865 if explicitIVIsSeq {
866 copy(explicitIV, c.out.seq[:])
867 } else {
868 if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil {
869 break
870 }
871 }
872 }
873 copy(b.data[recordHeaderLen+explicitIVLen:], data)
874 c.out.encrypt(b, explicitIVLen)
875 _, err = c.conn.Write(b.data)
876 if err != nil {
877 break
878 }
879 n += m
880 data = data[m:]
881 }
882 c.out.freeBlock(b)
883
884 if typ == recordTypeChangeCipherSpec {
Adam Langley80842bd2014-06-20 12:00:00 -0700885 err = c.out.changeCipherSpec(c.config)
Adam Langley95c29f32014-06-20 12:00:00 -0700886 if err != nil {
887 // Cannot call sendAlert directly,
888 // because we already hold c.out.Mutex.
889 c.tmp[0] = alertLevelError
890 c.tmp[1] = byte(err.(alert))
891 c.writeRecord(recordTypeAlert, c.tmp[0:2])
892 return n, c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
893 }
894 }
895 return
896}
897
David Benjamin83c0bc92014-08-04 01:23:53 -0400898func (c *Conn) doReadHandshake() ([]byte, error) {
899 if c.isDTLS {
900 return c.dtlsDoReadHandshake()
901 }
902
Adam Langley95c29f32014-06-20 12:00:00 -0700903 for c.hand.Len() < 4 {
904 if err := c.in.err; err != nil {
905 return nil, err
906 }
907 if err := c.readRecord(recordTypeHandshake); err != nil {
908 return nil, err
909 }
910 }
911
912 data := c.hand.Bytes()
913 n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
914 if n > maxHandshake {
915 return nil, c.in.setErrorLocked(c.sendAlert(alertInternalError))
916 }
917 for c.hand.Len() < 4+n {
918 if err := c.in.err; err != nil {
919 return nil, err
920 }
921 if err := c.readRecord(recordTypeHandshake); err != nil {
922 return nil, err
923 }
924 }
David Benjamin83c0bc92014-08-04 01:23:53 -0400925 return c.hand.Next(4 + n), nil
926}
927
928// readHandshake reads the next handshake message from
929// the record layer.
930// c.in.Mutex < L; c.out.Mutex < L.
931func (c *Conn) readHandshake() (interface{}, error) {
932 data, err := c.doReadHandshake()
933 if err != nil {
934 return nil, err
935 }
936
Adam Langley95c29f32014-06-20 12:00:00 -0700937 var m handshakeMessage
938 switch data[0] {
Adam Langley2ae77d22014-10-28 17:29:33 -0700939 case typeHelloRequest:
940 m = new(helloRequestMsg)
Adam Langley95c29f32014-06-20 12:00:00 -0700941 case typeClientHello:
David Benjamin83c0bc92014-08-04 01:23:53 -0400942 m = &clientHelloMsg{
943 isDTLS: c.isDTLS,
944 }
Adam Langley95c29f32014-06-20 12:00:00 -0700945 case typeServerHello:
David Benjamin83c0bc92014-08-04 01:23:53 -0400946 m = &serverHelloMsg{
947 isDTLS: c.isDTLS,
948 }
Adam Langley95c29f32014-06-20 12:00:00 -0700949 case typeNewSessionTicket:
950 m = new(newSessionTicketMsg)
951 case typeCertificate:
952 m = new(certificateMsg)
953 case typeCertificateRequest:
954 m = &certificateRequestMsg{
955 hasSignatureAndHash: c.vers >= VersionTLS12,
956 }
957 case typeCertificateStatus:
958 m = new(certificateStatusMsg)
959 case typeServerKeyExchange:
960 m = new(serverKeyExchangeMsg)
961 case typeServerHelloDone:
962 m = new(serverHelloDoneMsg)
963 case typeClientKeyExchange:
964 m = new(clientKeyExchangeMsg)
965 case typeCertificateVerify:
966 m = &certificateVerifyMsg{
967 hasSignatureAndHash: c.vers >= VersionTLS12,
968 }
969 case typeNextProtocol:
970 m = new(nextProtoMsg)
971 case typeFinished:
972 m = new(finishedMsg)
David Benjamin83c0bc92014-08-04 01:23:53 -0400973 case typeHelloVerifyRequest:
974 m = new(helloVerifyRequestMsg)
David Benjamind30a9902014-08-24 01:44:23 -0400975 case typeEncryptedExtensions:
976 m = new(encryptedExtensionsMsg)
Adam Langley95c29f32014-06-20 12:00:00 -0700977 default:
978 return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
979 }
980
981 // The handshake message unmarshallers
982 // expect to be able to keep references to data,
983 // so pass in a fresh copy that won't be overwritten.
984 data = append([]byte(nil), data...)
985
986 if !m.unmarshal(data) {
987 return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
988 }
989 return m, nil
990}
991
992// Write writes data to the connection.
993func (c *Conn) Write(b []byte) (int, error) {
994 if err := c.Handshake(); err != nil {
995 return 0, err
996 }
997
998 c.out.Lock()
999 defer c.out.Unlock()
1000
1001 if err := c.out.err; err != nil {
1002 return 0, err
1003 }
1004
1005 if !c.handshakeComplete {
1006 return 0, alertInternalError
1007 }
1008
Alex Chernyakhovsky4cd8c432014-11-01 19:39:08 -04001009 if c.config.Bugs.SendSpuriousAlert {
1010 c.sendAlertLocked(alertRecordOverflow)
1011 }
1012
Adam Langley95c29f32014-06-20 12:00:00 -07001013 // SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext
1014 // attack when using block mode ciphers due to predictable IVs.
1015 // This can be prevented by splitting each Application Data
1016 // record into two records, effectively randomizing the IV.
1017 //
1018 // http://www.openssl.org/~bodo/tls-cbc.txt
1019 // https://bugzilla.mozilla.org/show_bug.cgi?id=665814
1020 // http://www.imperialviolet.org/2012/01/15/beastfollowup.html
1021
1022 var m int
David Benjamin83c0bc92014-08-04 01:23:53 -04001023 if len(b) > 1 && c.vers <= VersionTLS10 && !c.isDTLS {
Adam Langley95c29f32014-06-20 12:00:00 -07001024 if _, ok := c.out.cipher.(cipher.BlockMode); ok {
1025 n, err := c.writeRecord(recordTypeApplicationData, b[:1])
1026 if err != nil {
1027 return n, c.out.setErrorLocked(err)
1028 }
1029 m, b = 1, b[1:]
1030 }
1031 }
1032
1033 n, err := c.writeRecord(recordTypeApplicationData, b)
1034 return n + m, c.out.setErrorLocked(err)
1035}
1036
Adam Langley2ae77d22014-10-28 17:29:33 -07001037func (c *Conn) handleRenegotiation() error {
1038 c.handshakeComplete = false
1039 if !c.isClient {
1040 panic("renegotiation should only happen for a client")
1041 }
1042
1043 msg, err := c.readHandshake()
1044 if err != nil {
1045 return err
1046 }
1047 _, ok := msg.(*helloRequestMsg)
1048 if !ok {
1049 c.sendAlert(alertUnexpectedMessage)
1050 return alertUnexpectedMessage
1051 }
1052
1053 return c.Handshake()
1054}
1055
Adam Langleycf2d4f42014-10-28 19:06:14 -07001056func (c *Conn) Renegotiate() error {
1057 if !c.isClient {
1058 helloReq := new(helloRequestMsg)
1059 c.writeRecord(recordTypeHandshake, helloReq.marshal())
1060 }
1061
1062 c.handshakeComplete = false
1063 return c.Handshake()
1064}
1065
Adam Langley95c29f32014-06-20 12:00:00 -07001066// Read can be made to time out and return a net.Error with Timeout() == true
1067// after a fixed time limit; see SetDeadline and SetReadDeadline.
1068func (c *Conn) Read(b []byte) (n int, err error) {
1069 if err = c.Handshake(); err != nil {
1070 return
1071 }
1072
1073 c.in.Lock()
1074 defer c.in.Unlock()
1075
1076 // Some OpenSSL servers send empty records in order to randomize the
1077 // CBC IV. So this loop ignores a limited number of empty records.
1078 const maxConsecutiveEmptyRecords = 100
1079 for emptyRecordCount := 0; emptyRecordCount <= maxConsecutiveEmptyRecords; emptyRecordCount++ {
1080 for c.input == nil && c.in.err == nil {
1081 if err := c.readRecord(recordTypeApplicationData); err != nil {
1082 // Soft error, like EAGAIN
1083 return 0, err
1084 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001085 if c.hand.Len() > 0 {
1086 // We received handshake bytes, indicating the
1087 // start of a renegotiation.
1088 if err := c.handleRenegotiation(); err != nil {
1089 return 0, err
1090 }
1091 continue
1092 }
Adam Langley95c29f32014-06-20 12:00:00 -07001093 }
1094 if err := c.in.err; err != nil {
1095 return 0, err
1096 }
1097
1098 n, err = c.input.Read(b)
David Benjamin83c0bc92014-08-04 01:23:53 -04001099 if c.input.off >= len(c.input.data) || c.isDTLS {
Adam Langley95c29f32014-06-20 12:00:00 -07001100 c.in.freeBlock(c.input)
1101 c.input = nil
1102 }
1103
1104 // If a close-notify alert is waiting, read it so that
1105 // we can return (n, EOF) instead of (n, nil), to signal
1106 // to the HTTP response reading goroutine that the
1107 // connection is now closed. This eliminates a race
1108 // where the HTTP response reading goroutine would
1109 // otherwise not observe the EOF until its next read,
1110 // by which time a client goroutine might have already
1111 // tried to reuse the HTTP connection for a new
1112 // request.
1113 // See https://codereview.appspot.com/76400046
1114 // and http://golang.org/issue/3514
1115 if ri := c.rawInput; ri != nil &&
1116 n != 0 && err == nil &&
1117 c.input == nil && len(ri.data) > 0 && recordType(ri.data[0]) == recordTypeAlert {
1118 if recErr := c.readRecord(recordTypeApplicationData); recErr != nil {
1119 err = recErr // will be io.EOF on closeNotify
1120 }
1121 }
1122
1123 if n != 0 || err != nil {
1124 return n, err
1125 }
1126 }
1127
1128 return 0, io.ErrNoProgress
1129}
1130
1131// Close closes the connection.
1132func (c *Conn) Close() error {
1133 var alertErr error
1134
1135 c.handshakeMutex.Lock()
1136 defer c.handshakeMutex.Unlock()
1137 if c.handshakeComplete {
1138 alertErr = c.sendAlert(alertCloseNotify)
1139 }
1140
1141 if err := c.conn.Close(); err != nil {
1142 return err
1143 }
1144 return alertErr
1145}
1146
1147// Handshake runs the client or server handshake
1148// protocol if it has not yet been run.
1149// Most uses of this package need not call Handshake
1150// explicitly: the first Read or Write will call it automatically.
1151func (c *Conn) Handshake() error {
1152 c.handshakeMutex.Lock()
1153 defer c.handshakeMutex.Unlock()
1154 if err := c.handshakeErr; err != nil {
1155 return err
1156 }
1157 if c.handshakeComplete {
1158 return nil
1159 }
1160
1161 if c.isClient {
1162 c.handshakeErr = c.clientHandshake()
1163 } else {
1164 c.handshakeErr = c.serverHandshake()
1165 }
1166 return c.handshakeErr
1167}
1168
1169// ConnectionState returns basic TLS details about the connection.
1170func (c *Conn) ConnectionState() ConnectionState {
1171 c.handshakeMutex.Lock()
1172 defer c.handshakeMutex.Unlock()
1173
1174 var state ConnectionState
1175 state.HandshakeComplete = c.handshakeComplete
1176 if c.handshakeComplete {
1177 state.Version = c.vers
1178 state.NegotiatedProtocol = c.clientProtocol
1179 state.DidResume = c.didResume
1180 state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback
David Benjaminfc7b0862014-09-06 13:21:53 -04001181 state.NegotiatedProtocolFromALPN = c.usedALPN
Adam Langley95c29f32014-06-20 12:00:00 -07001182 state.CipherSuite = c.cipherSuite
1183 state.PeerCertificates = c.peerCertificates
1184 state.VerifiedChains = c.verifiedChains
1185 state.ServerName = c.serverName
David Benjamind30a9902014-08-24 01:44:23 -04001186 state.ChannelID = c.channelID
Adam Langley95c29f32014-06-20 12:00:00 -07001187 }
1188
1189 return state
1190}
1191
1192// OCSPResponse returns the stapled OCSP response from the TLS server, if
1193// any. (Only valid for client connections.)
1194func (c *Conn) OCSPResponse() []byte {
1195 c.handshakeMutex.Lock()
1196 defer c.handshakeMutex.Unlock()
1197
1198 return c.ocspResponse
1199}
1200
1201// VerifyHostname checks that the peer certificate chain is valid for
1202// connecting to host. If so, it returns nil; if not, it returns an error
1203// describing the problem.
1204func (c *Conn) VerifyHostname(host string) error {
1205 c.handshakeMutex.Lock()
1206 defer c.handshakeMutex.Unlock()
1207 if !c.isClient {
1208 return errors.New("tls: VerifyHostname called on TLS server connection")
1209 }
1210 if !c.handshakeComplete {
1211 return errors.New("tls: handshake has not yet been performed")
1212 }
1213 return c.peerCertificates[0].VerifyHostname(host)
1214}