@@ -28,25 +28,44 @@ type Conn struct {
28
28
isClient bool
29
29
30
30
// constant after handshake; protected by handshakeMutex
31
- handshakeMutex sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
32
- handshakeErr error // error resulting from handshake
33
- vers uint16 // TLS version
34
- haveVers bool // version has been negotiated
35
- config * Config // configuration passed to constructor
31
+ handshakeMutex sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
32
+ handshakeErr error // error resulting from handshake
33
+ vers uint16 // TLS version
34
+ haveVers bool // version has been negotiated
35
+ config * Config // configuration passed to constructor
36
+ // handshakeComplete is true if the connection is currently transfering
37
+ // application data (i.e. is not currently processing a handshake).
36
38
handshakeComplete bool
37
- didResume bool // whether this connection was a session resumption
38
- cipherSuite uint16
39
- ocspResponse []byte // stapled OCSP response
40
- scts [][]byte // signed certificate timestamps from server
41
- peerCertificates []* x509.Certificate
39
+ // handshakes counts the number of handshakes performed on the
40
+ // connection so far. If renegotiation is disabled then this is either
41
+ // zero or one.
42
+ handshakes int
43
+ didResume bool // whether this connection was a session resumption
44
+ cipherSuite uint16
45
+ ocspResponse []byte // stapled OCSP response
46
+ scts [][]byte // signed certificate timestamps from server
47
+ peerCertificates []* x509.Certificate
42
48
// verifiedChains contains the certificate chains that we built, as
43
49
// opposed to the ones presented by the server.
44
50
verifiedChains [][]* x509.Certificate
45
51
// serverName contains the server name indicated by the client, if any.
46
52
serverName string
47
- // firstFinished contains the first Finished hash sent during the
48
- // handshake. This is the "tls-unique" channel binding value.
49
- firstFinished [12 ]byte
53
+ // secureRenegotiation is true if the server echoed the secure
54
+ // renegotiation extension. (This is meaningless as a server because
55
+ // renegotiation is not supported in that case.)
56
+ secureRenegotiation bool
57
+
58
+ // clientFinishedIsFirst is true if the client sent the first Finished
59
+ // message during the most recent handshake. This is recorded because
60
+ // the first transmitted Finished message is the tls-unique
61
+ // channel-binding value.
62
+ clientFinishedIsFirst bool
63
+ // clientFinished and serverFinished contain the Finished message sent
64
+ // by the client or server in the most recent handshake. This is
65
+ // retained to support the renegotiation extension and tls-unique
66
+ // channel-binding.
67
+ clientFinished [12 ]byte
68
+ serverFinished [12 ]byte
50
69
51
70
clientProtocol string
52
71
clientProtocolFallback bool
@@ -128,13 +147,6 @@ func (hc *halfConn) setErrorLocked(err error) error {
128
147
return err
129
148
}
130
149
131
- func (hc * halfConn ) error () error {
132
- hc .Lock ()
133
- err := hc .err
134
- hc .Unlock ()
135
- return err
136
- }
137
-
138
150
// prepareCipherSpec sets the encryption and MAC states
139
151
// that a subsequent changeCipherSpec will use.
140
152
func (hc * halfConn ) prepareCipherSpec (version uint16 , cipher interface {}, mac macFunction ) {
@@ -532,20 +544,20 @@ func (c *Conn) newRecordHeaderError(msg string) (err RecordHeaderError) {
532
544
func (c * Conn ) readRecord (want recordType ) error {
533
545
// Caller must be in sync with connection:
534
546
// handshake data if handshake not yet completed,
535
- // else application data. (We don't support renegotiation.)
547
+ // else application data.
536
548
switch want {
537
549
default :
538
550
c .sendAlert (alertInternalError )
539
551
return c .in .setErrorLocked (errors .New ("tls: unknown record type requested" ))
540
552
case recordTypeHandshake , recordTypeChangeCipherSpec :
541
553
if c .handshakeComplete {
542
554
c .sendAlert (alertInternalError )
543
- return c .in .setErrorLocked (errors .New ("tls: handshake or ChangeCipherSpec requested after handshake complete " ))
555
+ return c .in .setErrorLocked (errors .New ("tls: handshake or ChangeCipherSpec requested while not in handshake " ))
544
556
}
545
557
case recordTypeApplicationData :
546
558
if ! c .handshakeComplete {
547
559
c .sendAlert (alertInternalError )
548
- return c .in .setErrorLocked (errors .New ("tls: application data record requested before handshake complete " ))
560
+ return c .in .setErrorLocked (errors .New ("tls: application data record requested while in handshake " ))
549
561
}
550
562
}
551
563
@@ -669,7 +681,7 @@ Again:
669
681
670
682
case recordTypeHandshake :
671
683
// TODO(rsc): Should at least pick off connection close.
672
- if typ != want {
684
+ if typ != want && ! ( c . isClient && c . config . Renegotiation != RenegotiateNever ) {
673
685
return c .in .setErrorLocked (c .sendAlert (alertNoRenegotiation ))
674
686
}
675
687
c .hand .Write (data )
@@ -692,7 +704,7 @@ func (c *Conn) sendAlertLocked(err alert) error {
692
704
}
693
705
c .tmp [1 ] = byte (err )
694
706
695
- _ , writeErr := c .writeRecord (recordTypeAlert , c .tmp [0 :2 ])
707
+ _ , writeErr := c .writeRecordLocked (recordTypeAlert , c .tmp [0 :2 ])
696
708
if err == alertCloseNotify {
697
709
// closeNotify is a special case in that it isn't an error.
698
710
return writeErr
@@ -779,10 +791,10 @@ func (c *Conn) maxPayloadSizeForWrite(typ recordType, explicitIVLen int) int {
779
791
return payloadBytes
780
792
}
781
793
782
- // writeRecord writes a TLS record with the given type and payload
783
- // to the connection and updates the record layer state.
794
+ // writeRecordLocked writes a TLS record with the given type and payload to the
795
+ // connection and updates the record layer state.
784
796
// c.out.Mutex <= L.
785
- func (c * Conn ) writeRecord (typ recordType , data []byte ) (int , error ) {
797
+ func (c * Conn ) writeRecordLocked (typ recordType , data []byte ) (int , error ) {
786
798
b := c .out .newBlock ()
787
799
defer c .out .freeBlock (b )
788
800
@@ -855,6 +867,16 @@ func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) {
855
867
return n , nil
856
868
}
857
869
870
+ // writeRecord writes a TLS record with the given type and payload to the
871
+ // connection and updates the record layer state.
872
+ // L < c.out.Mutex.
873
+ func (c * Conn ) writeRecord (typ recordType , data []byte ) (int , error ) {
874
+ c .out .Lock ()
875
+ defer c .out .Unlock ()
876
+
877
+ return c .writeRecordLocked (typ , data )
878
+ }
879
+
858
880
// readHandshake reads the next handshake message from
859
881
// the record layer.
860
882
// c.in.Mutex < L; c.out.Mutex < L.
@@ -885,6 +907,8 @@ func (c *Conn) readHandshake() (interface{}, error) {
885
907
data = c .hand .Next (4 + n )
886
908
var m handshakeMessage
887
909
switch data [0 ] {
910
+ case typeHelloRequest :
911
+ m = new (helloRequestMsg )
888
912
case typeClientHello :
889
913
m = new (clientHelloMsg )
890
914
case typeServerHello :
@@ -971,18 +995,60 @@ func (c *Conn) Write(b []byte) (int, error) {
971
995
var m int
972
996
if len (b ) > 1 && c .vers <= VersionTLS10 {
973
997
if _ , ok := c .out .cipher .(cipher.BlockMode ); ok {
974
- n , err := c .writeRecord (recordTypeApplicationData , b [:1 ])
998
+ n , err := c .writeRecordLocked (recordTypeApplicationData , b [:1 ])
975
999
if err != nil {
976
1000
return n , c .out .setErrorLocked (err )
977
1001
}
978
1002
m , b = 1 , b [1 :]
979
1003
}
980
1004
}
981
1005
982
- n , err := c .writeRecord (recordTypeApplicationData , b )
1006
+ n , err := c .writeRecordLocked (recordTypeApplicationData , b )
983
1007
return n + m , c .out .setErrorLocked (err )
984
1008
}
985
1009
1010
+ // handleRenegotiation processes a HelloRequest handshake message.
1011
+ // c.in.Mutex <= L
1012
+ func (c * Conn ) handleRenegotiation () error {
1013
+ msg , err := c .readHandshake ()
1014
+ if err != nil {
1015
+ return err
1016
+ }
1017
+
1018
+ _ , ok := msg .(* helloRequestMsg )
1019
+ if ! ok {
1020
+ c .sendAlert (alertUnexpectedMessage )
1021
+ return alertUnexpectedMessage
1022
+ }
1023
+
1024
+ if ! c .isClient {
1025
+ return c .sendAlert (alertNoRenegotiation )
1026
+ }
1027
+
1028
+ switch c .config .Renegotiation {
1029
+ case RenegotiateNever :
1030
+ return c .sendAlert (alertNoRenegotiation )
1031
+ case RenegotiateOnceAsClient :
1032
+ if c .handshakes > 1 {
1033
+ return c .sendAlert (alertNoRenegotiation )
1034
+ }
1035
+ case RenegotiateFreelyAsClient :
1036
+ // Ok.
1037
+ default :
1038
+ c .sendAlert (alertInternalError )
1039
+ return errors .New ("tls: unknown Renegotiation value" )
1040
+ }
1041
+
1042
+ c .handshakeMutex .Lock ()
1043
+ defer c .handshakeMutex .Unlock ()
1044
+
1045
+ c .handshakeComplete = false
1046
+ if c .handshakeErr = c .clientHandshake (); c .handshakeErr == nil {
1047
+ c .handshakes ++
1048
+ }
1049
+ return c .handshakeErr
1050
+ }
1051
+
986
1052
// Read can be made to time out and return a net.Error with Timeout() == true
987
1053
// after a fixed time limit; see SetDeadline and SetReadDeadline.
988
1054
func (c * Conn ) Read (b []byte ) (n int , err error ) {
@@ -1007,6 +1073,13 @@ func (c *Conn) Read(b []byte) (n int, err error) {
1007
1073
// Soft error, like EAGAIN
1008
1074
return 0 , err
1009
1075
}
1076
+ if c .hand .Len () > 0 {
1077
+ // We received handshake bytes, indicating the
1078
+ // start of a renegotiation.
1079
+ if err := c .handleRenegotiation (); err != nil {
1080
+ return 0 , err
1081
+ }
1082
+ }
1010
1083
}
1011
1084
if err := c .in .err ; err != nil {
1012
1085
return 0 , err
@@ -1087,20 +1160,45 @@ func (c *Conn) Close() error {
1087
1160
// Most uses of this package need not call Handshake
1088
1161
// explicitly: the first Read or Write will call it automatically.
1089
1162
func (c * Conn ) Handshake () error {
1163
+ // c.handshakeErr and c.handshakeComplete are protected by
1164
+ // c.handshakeMutex. In order to perform a handshake, we need to lock
1165
+ // c.in also and c.handshakeMutex must be locked after c.in.
1166
+ //
1167
+ // However, if a Read() operation is hanging then it'll be holding the
1168
+ // lock on c.in and so taking it here would cause all operations that
1169
+ // need to check whether a handshake is pending (such as Write) to
1170
+ // block.
1171
+ //
1172
+ // Thus we take c.handshakeMutex first and, if we find that a handshake
1173
+ // is needed, then we unlock, acquire c.in and c.handshakeMutex in the
1174
+ // correct order, and check again.
1090
1175
c .handshakeMutex .Lock ()
1091
1176
defer c .handshakeMutex .Unlock ()
1092
- if err := c .handshakeErr ; err != nil {
1093
- return err
1094
- }
1095
- if c .handshakeComplete {
1096
- return nil
1177
+
1178
+ for i := 0 ; i < 2 ; i ++ {
1179
+ if i == 1 {
1180
+ c .handshakeMutex .Unlock ()
1181
+ c .in .Lock ()
1182
+ defer c .in .Unlock ()
1183
+ c .handshakeMutex .Lock ()
1184
+ }
1185
+
1186
+ if err := c .handshakeErr ; err != nil {
1187
+ return err
1188
+ }
1189
+ if c .handshakeComplete {
1190
+ return nil
1191
+ }
1097
1192
}
1098
1193
1099
1194
if c .isClient {
1100
1195
c .handshakeErr = c .clientHandshake ()
1101
1196
} else {
1102
1197
c .handshakeErr = c .serverHandshake ()
1103
1198
}
1199
+ if c .handshakeErr == nil {
1200
+ c .handshakes ++
1201
+ }
1104
1202
return c .handshakeErr
1105
1203
}
1106
1204
@@ -1123,7 +1221,11 @@ func (c *Conn) ConnectionState() ConnectionState {
1123
1221
state .SignedCertificateTimestamps = c .scts
1124
1222
state .OCSPResponse = c .ocspResponse
1125
1223
if ! c .didResume {
1126
- state .TLSUnique = c .firstFinished [:]
1224
+ if c .clientFinishedIsFirst {
1225
+ state .TLSUnique = c .clientFinished [:]
1226
+ } else {
1227
+ state .TLSUnique = c .serverFinished [:]
1228
+ }
1127
1229
}
1128
1230
}
1129
1231
0 commit comments