~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/crypto/tls/conn.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
        haveVers          bool       // version has been negotiated
32
32
        config            *Config    // configuration passed to constructor
33
33
        handshakeComplete bool
 
34
        didResume         bool // whether this connection was a session resumption
34
35
        cipherSuite       uint16
35
36
        ocspResponse      []byte // stapled OCSP response
36
37
        peerCertificates  []*x509.Certificate
44
45
        clientProtocolFallback bool
45
46
 
46
47
        // first permanent error
47
 
        errMutex sync.Mutex
48
 
        err      error
 
48
        connErr
49
49
 
50
50
        // input/output
51
51
        in, out  halfConn     // in.Mutex < out.Mutex
56
56
        tmp [16]byte
57
57
}
58
58
 
59
 
func (c *Conn) setError(err error) error {
60
 
        c.errMutex.Lock()
61
 
        defer c.errMutex.Unlock()
62
 
 
63
 
        if c.err == nil {
64
 
                c.err = err
 
59
type connErr struct {
 
60
        mu    sync.Mutex
 
61
        value error
 
62
}
 
63
 
 
64
func (e *connErr) setError(err error) error {
 
65
        e.mu.Lock()
 
66
        defer e.mu.Unlock()
 
67
 
 
68
        if e.value == nil {
 
69
                e.value = err
65
70
        }
66
71
        return err
67
72
}
68
73
 
69
 
func (c *Conn) error() error {
70
 
        c.errMutex.Lock()
71
 
        defer c.errMutex.Unlock()
72
 
 
73
 
        return c.err
 
74
func (e *connErr) error() error {
 
75
        e.mu.Lock()
 
76
        defer e.mu.Unlock()
 
77
        return e.value
74
78
}
75
79
 
76
80
// Access to net.Conn methods.
487
491
                return err
488
492
        }
489
493
        typ := recordType(b.data[0])
 
494
 
 
495
        // No valid TLS record has a type of 0x80, however SSLv2 handshakes
 
496
        // start with a uint16 length where the MSB is set and the first record
 
497
        // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
 
498
        // an SSLv2 client.
 
499
        if want == recordTypeHandshake && typ == 0x80 {
 
500
                c.sendAlert(alertProtocolVersion)
 
501
                return errors.New("tls: unsupported SSLv2 handshake received")
 
502
        }
 
503
 
490
504
        vers := uint16(b.data[1])<<8 | uint16(b.data[2])
491
505
        n := int(b.data[3])<<8 | int(b.data[4])
492
506
        if c.haveVers && vers != c.vers {
499
513
                // First message, be extra suspicious:
500
514
                // this might not be a TLS client.
501
515
                // Bail out before reading a full 'body', if possible.
502
 
                // The current max version is 3.1. 
 
516
                // The current max version is 3.1.
503
517
                // If the version is >= 16.0, it's probably not real.
504
518
                // Similarly, a clientHello message encodes in
505
519
                // well under a kilobyte.  If the length is >= 12 kB,
590
604
// sendAlert sends a TLS alert message.
591
605
// c.out.Mutex <= L.
592
606
func (c *Conn) sendAlertLocked(err alert) error {
593
 
        c.tmp[0] = alertLevelError
594
 
        if err == alertNoRenegotiation {
 
607
        switch err {
 
608
        case alertNoRenegotiation, alertCloseNotify:
595
609
                c.tmp[0] = alertLevelWarning
 
610
        default:
 
611
                c.tmp[0] = alertLevelError
596
612
        }
597
613
        c.tmp[1] = byte(err)
598
614
        c.writeRecord(recordTypeAlert, c.tmp[0:2])
650
666
                        c.tmp[0] = alertLevelError
651
667
                        c.tmp[1] = byte(err.(alert))
652
668
                        c.writeRecord(recordTypeAlert, c.tmp[0:2])
653
 
                        c.err = &net.OpError{Op: "local error", Err: err}
654
 
                        return n, c.err
 
669
                        return n, c.setError(&net.OpError{Op: "local error", Err: err})
655
670
                }
656
671
        }
657
672
        return
662
677
// c.in.Mutex < L; c.out.Mutex < L.
663
678
func (c *Conn) readHandshake() (interface{}, error) {
664
679
        for c.hand.Len() < 4 {
665
 
                if c.err != nil {
666
 
                        return nil, c.err
 
680
                if err := c.error(); err != nil {
 
681
                        return nil, err
667
682
                }
668
683
                if err := c.readRecord(recordTypeHandshake); err != nil {
669
684
                        return nil, err
674
689
        n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
675
690
        if n > maxHandshake {
676
691
                c.sendAlert(alertInternalError)
677
 
                return nil, c.err
 
692
                return nil, c.error()
678
693
        }
679
694
        for c.hand.Len() < 4+n {
680
 
                if c.err != nil {
681
 
                        return nil, c.err
 
695
                if err := c.error(); err != nil {
 
696
                        return nil, err
682
697
                }
683
698
                if err := c.readRecord(recordTypeHandshake); err != nil {
684
699
                        return nil, err
728
743
 
729
744
// Write writes data to the connection.
730
745
func (c *Conn) Write(b []byte) (int, error) {
731
 
        if c.err != nil {
732
 
                return 0, c.err
 
746
        if err := c.error(); err != nil {
 
747
                return 0, err
733
748
        }
734
749
 
735
 
        if c.err = c.Handshake(); c.err != nil {
736
 
                return 0, c.err
 
750
        if err := c.Handshake(); err != nil {
 
751
                return 0, c.setError(err)
737
752
        }
738
753
 
739
754
        c.out.Lock()
743
758
                return 0, alertInternalError
744
759
        }
745
760
 
746
 
        var n int
747
 
        n, c.err = c.writeRecord(recordTypeApplicationData, b)
748
 
        return n, c.err
 
761
        // SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext
 
762
        // attack when using block mode ciphers due to predictable IVs.
 
763
        // This can be prevented by splitting each Application Data
 
764
        // record into two records, effectively randomizing the IV.
 
765
        //
 
766
        // http://www.openssl.org/~bodo/tls-cbc.txt
 
767
        // https://bugzilla.mozilla.org/show_bug.cgi?id=665814
 
768
        // http://www.imperialviolet.org/2012/01/15/beastfollowup.html
 
769
 
 
770
        var m int
 
771
        if len(b) > 1 && c.vers <= versionTLS10 {
 
772
                if _, ok := c.out.cipher.(cipher.BlockMode); ok {
 
773
                        n, err := c.writeRecord(recordTypeApplicationData, b[:1])
 
774
                        if err != nil {
 
775
                                return n, c.setError(err)
 
776
                        }
 
777
                        m, b = 1, b[1:]
 
778
                }
 
779
        }
 
780
 
 
781
        n, err := c.writeRecord(recordTypeApplicationData, b)
 
782
        return n + m, c.setError(err)
749
783
}
750
784
 
751
785
// Read can be made to time out and return a net.Error with Timeout() == true
758
792
        c.in.Lock()
759
793
        defer c.in.Unlock()
760
794
 
761
 
        for c.input == nil && c.err == nil {
 
795
        for c.input == nil && c.error() == nil {
762
796
                if err := c.readRecord(recordTypeApplicationData); err != nil {
763
797
                        // Soft error, like EAGAIN
764
798
                        return 0, err
765
799
                }
766
800
        }
767
 
        if c.err != nil {
768
 
                return 0, c.err
 
801
        if err := c.error(); err != nil {
 
802
                return 0, err
769
803
        }
770
804
        n, err = c.input.Read(b)
771
805
        if c.input.off >= len(c.input.data) {
819
853
        state.HandshakeComplete = c.handshakeComplete
820
854
        if c.handshakeComplete {
821
855
                state.NegotiatedProtocol = c.clientProtocol
 
856
                state.DidResume = c.didResume
822
857
                state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback
823
858
                state.CipherSuite = c.cipherSuite
824
859
                state.PeerCertificates = c.peerCertificates