R=rsc, r http://go/go-review/1025029tls13
@@ -92,12 +92,12 @@ type encryptor interface { | |||
func mutualVersion(theirMajor, theirMinor uint8) (major, minor uint8, ok bool) { | |||
// We don't deal with peers < TLS 1.0 (aka version 3.1). | |||
if theirMajor < 3 || theirMajor == 3 && theirMinor < 1 { | |||
return 0, 0, false; | |||
return 0, 0, false | |||
} | |||
major = 3; | |||
minor = 2; | |||
if theirMinor < minor { | |||
minor = theirMinor; | |||
minor = theirMinor | |||
} | |||
ok = true; | |||
return; | |||
@@ -19,7 +19,7 @@ type clientHelloMsg struct { | |||
func (m *clientHelloMsg) marshal() []byte { | |||
if m.raw != nil { | |||
return m.raw; | |||
return m.raw | |||
} | |||
length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods); | |||
@@ -50,7 +50,7 @@ func (m *clientHelloMsg) marshal() []byte { | |||
func (m *clientHelloMsg) unmarshal(data []byte) bool { | |||
if len(data) < 39 { | |||
return false; | |||
return false | |||
} | |||
m.raw = data; | |||
m.major = data[4]; | |||
@@ -58,31 +58,31 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool { | |||
m.random = data[6:38]; | |||
sessionIdLen := int(data[38]); | |||
if sessionIdLen > 32 || len(data) < 39 + sessionIdLen { | |||
return false; | |||
return false | |||
} | |||
m.sessionId = data[39 : 39 + sessionIdLen]; | |||
data = data[39 + sessionIdLen : len(data)]; | |||
if len(data) < 2 { | |||
return false; | |||
return false | |||
} | |||
// cipherSuiteLen is the number of bytes of cipher suite numbers. Since | |||
// they are uint16s, the number must be even. | |||
cipherSuiteLen := int(data[0])<<8 | int(data[1]); | |||
if cipherSuiteLen % 2 == 1 || len(data) < 2 + cipherSuiteLen { | |||
return false; | |||
return false | |||
} | |||
numCipherSuites := cipherSuiteLen / 2; | |||
m.cipherSuites = make([]uint16, numCipherSuites); | |||
for i := 0; i < numCipherSuites; i++ { | |||
m.cipherSuites[i] = uint16(data[2 + 2*i])<<8 | uint16(data[3 + 2*i]); | |||
m.cipherSuites[i] = uint16(data[2 + 2*i])<<8 | uint16(data[3 + 2*i]) | |||
} | |||
data = data[2 + cipherSuiteLen : len(data)]; | |||
if len(data) < 2 { | |||
return false; | |||
return false | |||
} | |||
compressionMethodsLen := int(data[0]); | |||
if len(data) < 1 + compressionMethodsLen { | |||
return false; | |||
return false | |||
} | |||
m.compressionMethods = data[1 : 1 + compressionMethodsLen]; | |||
@@ -101,7 +101,7 @@ type serverHelloMsg struct { | |||
func (m *serverHelloMsg) marshal() []byte { | |||
if m.raw != nil { | |||
return m.raw; | |||
return m.raw | |||
} | |||
length := 38+len(m.sessionId); | |||
@@ -131,12 +131,12 @@ type certificateMsg struct { | |||
func (m *certificateMsg) marshal() (x []byte) { | |||
if m.raw != nil { | |||
return m.raw; | |||
return m.raw | |||
} | |||
var i int; | |||
for _, slice := range m.certificates { | |||
i += len(slice); | |||
i += len(slice) | |||
} | |||
length := 3 + 3*len(m.certificates) + i; | |||
@@ -179,7 +179,7 @@ type clientKeyExchangeMsg struct { | |||
func (m *clientKeyExchangeMsg) marshal() []byte { | |||
if m.raw != nil { | |||
return m.raw; | |||
return m.raw | |||
} | |||
length := len(m.ciphertext)+2; | |||
x := make([]byte, length+4); | |||
@@ -198,11 +198,11 @@ func (m *clientKeyExchangeMsg) marshal() []byte { | |||
func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool { | |||
m.raw = data; | |||
if len(data) < 7 { | |||
return false; | |||
return false | |||
} | |||
cipherTextLen := int(data[4])<<8 | int(data[5]); | |||
if len(data) != 6 + cipherTextLen { | |||
return false; | |||
return false | |||
} | |||
m.ciphertext = data[6:len(data)]; | |||
return true; | |||
@@ -215,7 +215,7 @@ type finishedMsg struct { | |||
func (m *finishedMsg) marshal() (x []byte) { | |||
if m.raw != nil { | |||
return m.raw; | |||
return m.raw | |||
} | |||
x = make([]byte, 16); | |||
@@ -229,7 +229,7 @@ func (m *finishedMsg) marshal() (x []byte) { | |||
func (m *finishedMsg) unmarshal(data []byte) bool { | |||
m.raw = data; | |||
if len(data) != 4+12 { | |||
return false; | |||
return false | |||
} | |||
m.verifyData = data[4:len(data)]; | |||
return true; | |||
@@ -62,7 +62,7 @@ func TestMarshalUnmarshal(t *testing.T) { | |||
func randomBytes(n int, rand *rand.Rand) []byte { | |||
r := make([]byte, n); | |||
for i := 0; i < n; i++ { | |||
r[i] = byte(rand.Int31()); | |||
r[i] = byte(rand.Int31()) | |||
} | |||
return r; | |||
} | |||
@@ -75,7 +75,7 @@ func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { | |||
m.sessionId = randomBytes(rand.Intn(32), rand); | |||
m.cipherSuites = make([]uint16, rand.Intn(63) + 1); | |||
for i := 0; i < len(m.cipherSuites); i++ { | |||
m.cipherSuites[i] = uint16(rand.Int31()); | |||
m.cipherSuites[i] = uint16(rand.Int31()) | |||
} | |||
m.compressionMethods = randomBytes(rand.Intn(63) + 1, rand); | |||
@@ -17,7 +17,7 @@ type zeroSource struct{} | |||
func (zeroSource) Read(b []byte) (n int, err os.Error) { | |||
for i := range b { | |||
b[i] = 0; | |||
b[i] = 0 | |||
} | |||
return len(b), nil; | |||
@@ -56,12 +56,12 @@ func testClientHelloFailure(t *testing.T, clientHello interface{}, expectedAlert | |||
err := script.Perform(0, []*script.Event{send, recvAlert, close1, recvState, close2}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} | |||
func TestSimpleError(t *testing.T) { | |||
testClientHelloFailure(t, &serverHelloDoneMsg{}, alertUnexpectedMessage); | |||
testClientHelloFailure(t, &serverHelloDoneMsg{}, alertUnexpectedMessage) | |||
} | |||
var badProtocolVersions = []uint8{0, 0, 0, 5, 1, 0, 1, 5, 2, 0, 2, 5, 3, 0} | |||
@@ -91,7 +91,7 @@ func TestNoCompressionOverlap(t *testing.T) { | |||
func matchServerHello(v interface{}) bool { | |||
serverHello, ok := v.(*serverHelloMsg); | |||
if !ok { | |||
return false; | |||
return false | |||
} | |||
return serverHello.major == 3 && | |||
serverHello.minor == 2 && | |||
@@ -111,7 +111,7 @@ func TestAlertForwarding(t *testing.T) { | |||
err := script.Perform(0, []*script.Event{sendAlert, recvAlert, closeWriter, closeControl}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} | |||
@@ -124,14 +124,14 @@ func TestClose(t *testing.T) { | |||
err := script.Perform(0, []*script.Event{close, closed1, closed2}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} | |||
func matchCertificate(v interface{}) bool { | |||
cert, ok := v.(*certificateMsg); | |||
if !ok { | |||
return false; | |||
return false | |||
} | |||
return len(cert.certificates) == 1 && | |||
bytes.Compare(cert.certificates[0], testCertificate) == 0; | |||
@@ -150,7 +150,7 @@ func matchDone(v interface{}) bool { | |||
func matchFinished(v interface{}) bool { | |||
finished, ok := v.(*finishedMsg); | |||
if !ok { | |||
return false; | |||
return false | |||
} | |||
return bytes.Compare(finished.verifyData, fromHex("29122ae11453e631487b02ed")) == 0; | |||
} | |||
@@ -187,7 +187,7 @@ func TestFullHandshake(t *testing.T) { | |||
err := script.Perform(0, []*script.Event{sendHello, setVersion, recvHello, recvCert, recvDone, sendCKX, sendCCS, recvNCS, sendFinished, setCipher, recvConnectionState, recvFinished}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} | |||
@@ -35,7 +35,7 @@ func pHash(result, secret, seed []byte, hash hash.Hash) { | |||
b := h.Sum(); | |||
todo := len(b); | |||
if j+todo > len(result) { | |||
todo = len(result)-j; | |||
todo = len(result)-j | |||
} | |||
bytes.Copy(result[j : j+todo], b); | |||
j += todo; | |||
@@ -61,7 +61,7 @@ func pRF11(result, secret, label, seed []byte) { | |||
pHash(result2, s2, labelAndSeed, hashSHA1); | |||
for i, b := range result2 { | |||
result[i] ^= b; | |||
result[i] ^= b | |||
} | |||
} | |||
@@ -109,7 +109,7 @@ type finishedHash struct { | |||
} | |||
func newFinishedHash() finishedHash { | |||
return finishedHash{md5.New(), sha1.New(), md5.New(), sha1.New()}; | |||
return finishedHash{md5.New(), sha1.New(), md5.New(), sha1.New()} | |||
} | |||
func (h finishedHash) Write(msg []byte) (n int, err os.Error) { | |||
@@ -28,7 +28,7 @@ func TestSplitPreMasterSecret(t *testing.T) { | |||
s1 := hex.EncodeToString(out1); | |||
s2 := hex.EncodeToString(out2); | |||
if s1 != test.out1 || s2 != test.out2 { | |||
t.Errorf("#%d: got: (%s, %s) want: (%s, %s)", i, s1, s2, test.out1, test.out2); | |||
t.Errorf("#%d: got: (%s, %s) want: (%s, %s)", i, s1, s2, test.out1, test.out2) | |||
} | |||
} | |||
} | |||
@@ -58,7 +58,7 @@ func TestKeysFromPreMasterSecret(t *testing.T) { | |||
serverMACString != test.serverMAC || | |||
clientKeyString != test.clientKey || | |||
serverKeyString != test.serverKey { | |||
t.Errorf("#%d: got: (%s, %s, %s, %s, %s) want: (%s, %s, %s, %s %s)", i, masterString, clientMACString, serverMACString, clientKeyString, serverMACString, test.masterSecret, test.clientMAC, test.serverMAC, test.clientKey, test.serverKey); | |||
t.Errorf("#%d: got: (%s, %s, %s, %s, %s) want: (%s, %s, %s, %s %s)", i, masterString, clientMACString, serverMACString, clientKeyString, serverMACString, test.masterSecret, test.clientMAC, test.serverMAC, test.clientKey, test.serverKey) | |||
} | |||
} | |||
} | |||
@@ -73,13 +73,13 @@ type recordProcessor struct { | |||
func drainRequestChannel(requestChan <-chan interface{}, c ConnectionState) { | |||
for v := range requestChan { | |||
if closed(requestChan) { | |||
return; | |||
return | |||
} | |||
switch r := v.(type) { | |||
case getConnectionState: | |||
r.reply <- c; | |||
r.reply <- c | |||
case waitConnectionState: | |||
r.reply <- c; | |||
r.reply <- c | |||
} | |||
} | |||
} | |||
@@ -104,11 +104,11 @@ func (p *recordProcessor) loop(appDataChan chan<- []byte, requestChan <-chan int | |||
p.appDataSend = nil; | |||
p.recordRead = p.recordChan; | |||
case c := <-controlChan: | |||
p.processControlMsg(c); | |||
p.processControlMsg(c) | |||
case r := <-requestChan: | |||
p.processRequestMsg(r); | |||
p.processRequestMsg(r) | |||
case r := <-p.recordRead: | |||
p.processRecord(r); | |||
p.processRecord(r) | |||
} | |||
} | |||
@@ -121,7 +121,7 @@ func (p *recordProcessor) loop(appDataChan chan<- []byte, requestChan <-chan int | |||
close(handshakeChan); | |||
if len(p.appData) > 0 { | |||
appDataChan <- p.appData; | |||
appDataChan <- p.appData | |||
} | |||
close(appDataChan); | |||
} | |||
@@ -134,10 +134,10 @@ func (p *recordProcessor) processRequestMsg(requestMsg interface{}) { | |||
switch r := requestMsg.(type) { | |||
case getConnectionState: | |||
r.reply <- p.connState; | |||
r.reply <- p.connState | |||
case waitConnectionState: | |||
if p.connState.HandshakeComplete { | |||
r.reply <- p.connState; | |||
r.reply <- p.connState | |||
} | |||
p.waitQueue.PushBack(r.reply); | |||
} | |||
@@ -156,7 +156,7 @@ func (p *recordProcessor) processControlMsg(msg interface{}) { | |||
func (p *recordProcessor) wakeWaiters() { | |||
for i := p.waitQueue.Front(); i != nil; i = i.Next() { | |||
i.Value.(chan<- ConnectionState) <- p.connState; | |||
i.Value.(chan<- ConnectionState) <- p.connState | |||
} | |||
p.waitQueue.Init(); | |||
} | |||
@@ -188,7 +188,7 @@ func (p *recordProcessor) processRecord(r *record) { | |||
switch r.contentType { | |||
case recordTypeHandshake: | |||
p.processHandshakeRecord(r.payload[0 : len(r.payload) - p.mac.Size()]); | |||
p.processHandshakeRecord(r.payload[0 : len(r.payload) - p.mac.Size()]) | |||
case recordTypeChangeCipherSpec: | |||
if len(r.payload) != 1 || r.payload[0] != 1 { | |||
p.error(alertUnexpectedMessage); | |||
@@ -221,7 +221,7 @@ func (p *recordProcessor) processRecord(r *record) { | |||
func (p *recordProcessor) processHandshakeRecord(data []byte) { | |||
if p.handshakeBuf == nil { | |||
p.handshakeBuf = data; | |||
p.handshakeBuf = data | |||
} else { | |||
if len(p.handshakeBuf) > maxHandshakeMsg { | |||
p.error(alertInternalError); | |||
@@ -238,7 +238,7 @@ func (p *recordProcessor) processHandshakeRecord(data []byte) { | |||
int(p.handshakeBuf[2])<<8 | | |||
int(p.handshakeBuf[3]); | |||
if handshakeLen + 4 > len(p.handshakeBuf) { | |||
break; | |||
break | |||
} | |||
bytes := p.handshakeBuf[0 : handshakeLen + 4]; | |||
@@ -249,7 +249,7 @@ func (p *recordProcessor) processHandshakeRecord(data []byte) { | |||
// forwarding application data. | |||
m := new(finishedMsg); | |||
if !m.unmarshal(bytes) { | |||
p.error(alertUnexpectedMessage); | |||
p.error(alertUnexpectedMessage) | |||
} | |||
p.handshakeChan <- m; | |||
var ok bool; | |||
@@ -283,11 +283,11 @@ func parseHandshakeMsg(data []byte) (interface{}, bool) { | |||
switch data[0] { | |||
case typeClientHello: | |||
m = new(clientHelloMsg); | |||
m = new(clientHelloMsg) | |||
case typeClientKeyExchange: | |||
m = new(clientKeyExchangeMsg); | |||
m = new(clientKeyExchangeMsg) | |||
default: | |||
return nil, false; | |||
return nil, false | |||
} | |||
ok := m.unmarshal(data); | |||
@@ -40,7 +40,7 @@ func TestNullConnectionState(t *testing.T) { | |||
err := script.Perform(0, []*script.Event{sendReq, getReply}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} | |||
@@ -61,7 +61,7 @@ func TestWaitConnectionState(t *testing.T) { | |||
err := script.Perform(0, []*script.Event{sendReq, sendReq2, getReply2, sendState, getReply}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} | |||
@@ -79,7 +79,7 @@ func TestHandshakeAssembly(t *testing.T) { | |||
err := script.Perform(0, []*script.Event{send1, send2, send3, recvMsg}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} | |||
@@ -95,7 +95,7 @@ func TestEarlyApplicationData(t *testing.T) { | |||
err := script.Perform(0, []*script.Event{send, recv}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} | |||
@@ -114,7 +114,7 @@ func TestApplicationData(t *testing.T) { | |||
err := script.Perform(0, []*script.Event{send1, recv1, send2, send3, recv2}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} | |||
@@ -132,6 +132,6 @@ func TestInvalidChangeCipherSpec(t *testing.T) { | |||
err := script.Perform(0, []*script.Event{send1, recv1, send2, close, close2}); | |||
if err != nil { | |||
t.Errorf("Got error: %s", err); | |||
t.Errorf("Got error: %s", err) | |||
} | |||
} |
@@ -23,18 +23,18 @@ func recordReader(c chan<- *record, source io.Reader) { | |||
var header [5]byte; | |||
n, _ := buf.Read(header[0:len(header)]); | |||
if n != 5 { | |||
return; | |||
return | |||
} | |||
recordLength := int(header[3])<<8 | int(header[4]); | |||
if recordLength > maxTLSCiphertext { | |||
return; | |||
return | |||
} | |||
payload := make([]byte, recordLength); | |||
n, _ = buf.Read(payload); | |||
if n != recordLength { | |||
return; | |||
return | |||
} | |||
c <- &record{recordType(header[0]), header[1], header[2], payload}; | |||
@@ -12,10 +12,10 @@ import ( | |||
func matchRecord(r1, r2 *record) bool { | |||
if (r1 == nil) != (r2 == nil) { | |||
return false; | |||
return false | |||
} | |||
if r1 == nil { | |||
return true; | |||
return true | |||
} | |||
return r1.contentType == r2.contentType && | |||
r1.major == r2.major && | |||
@@ -63,11 +63,11 @@ func matchRecordReaderOutput(t *testing.T, i int, test recordReaderTest, c <-cha | |||
break; | |||
} | |||
if !matchRecord(r1, r2) { | |||
t.Errorf("#%d (%d) got:%#v want:%#v", i, j, r2, r1); | |||
t.Errorf("#%d (%d) got:%#v want:%#v", i, j, r2, r1) | |||
} | |||
} | |||
<-c; | |||
if !closed(c) { | |||
t.Errorf("#%d: channel didn't close", i); | |||
t.Errorf("#%d: channel didn't close", i) | |||
} | |||
} |
@@ -53,7 +53,7 @@ func (w *recordWriter) loop(writer io.Writer, appChan <-chan []byte, controlChan | |||
for !w.shutdown { | |||
msg := <-controlChan; | |||
if _, ok := msg.(writerEnableApplicationData); ok { | |||
break; | |||
break | |||
} | |||
w.processControlMessage(msg); | |||
} | |||
@@ -67,9 +67,9 @@ func (w *recordWriter) loop(writer io.Writer, appChan <-chan []byte, controlChan | |||
select { | |||
case controlMsg := <-controlChan: | |||
w.processControlMessage(controlMsg); | |||
w.processControlMessage(controlMsg) | |||
case appMsg := <-appChan: | |||
w.processAppMessage(appMsg); | |||
w.processAppMessage(appMsg) | |||
} | |||
} | |||
@@ -77,13 +77,13 @@ func (w *recordWriter) loop(writer io.Writer, appChan <-chan []byte, controlChan | |||
go func() { | |||
for _ = range appChan { | |||
} | |||
}(); | |||
}() | |||
} | |||
if !closed(controlChan) { | |||
go func() { | |||
for _ = range controlChan { | |||
} | |||
}(); | |||
}() | |||
} | |||
} | |||
@@ -142,12 +142,12 @@ func (w *recordWriter) processControlMessage(controlMsg interface{}) { | |||
w.major = msg.major; | |||
w.minor = msg.minor; | |||
case alert: | |||
w.writeRecord(&record{recordTypeAlert, w.major, w.minor, []byte{byte(msg.level), byte(msg.error)}}); | |||
w.writeRecord(&record{recordTypeAlert, w.major, w.minor, []byte{byte(msg.level), byte(msg.error)}}) | |||
case handshakeMessage: | |||
// TODO(agl): marshal may return a slice too large for a single record. | |||
w.writeRecord(&record{recordTypeHandshake, w.major, w.minor, msg.marshal()}); | |||
w.writeRecord(&record{recordTypeHandshake, w.major, w.minor, msg.marshal()}) | |||
default: | |||
fmt.Printf("processControlMessage: unknown %#v\n", msg); | |||
fmt.Printf("processControlMessage: unknown %#v\n", msg) | |||
} | |||
} | |||
@@ -162,7 +162,7 @@ func (w *recordWriter) processAppMessage(appMsg []byte) { | |||
for done < len(appMsg) { | |||
todo := len(appMsg); | |||
if todo > maxTLSPlaintext { | |||
todo = maxTLSPlaintext; | |||
todo = maxTLSPlaintext | |||
} | |||
w.writeRecord(&record{recordTypeApplicationData, w.major, w.minor, appMsg[done : done+todo]}); | |||
done += todo; | |||
@@ -32,7 +32,7 @@ func timeout(c chan<- bool, nsecs int64) { | |||
func (tls *Conn) Read(p []byte) (int, os.Error) { | |||
if len(tls.readBuf) == 0 { | |||
if tls.eof { | |||
return 0, os.EOF; | |||
return 0, os.EOF | |||
} | |||
var timeoutChan chan bool; | |||
@@ -43,15 +43,15 @@ func (tls *Conn) Read(p []byte) (int, os.Error) { | |||
select { | |||
case b := <-tls.readChan: | |||
tls.readBuf = b; | |||
tls.readBuf = b | |||
case <-timeoutChan: | |||
return 0, os.EAGAIN; | |||
return 0, os.EAGAIN | |||
} | |||
// TLS distinguishes between orderly closes and truncations. An | |||
// orderly close is represented by a zero length slice. | |||
if closed(tls.readChan) { | |||
return 0, io.ErrUnexpectedEOF; | |||
return 0, io.ErrUnexpectedEOF | |||
} | |||
if len(tls.readBuf) == 0 { | |||
tls.eof = true; | |||
@@ -66,7 +66,7 @@ func (tls *Conn) Read(p []byte) (int, os.Error) { | |||
func (tls *Conn) Write(p []byte) (int, os.Error) { | |||
if tls.eof || closed(tls.readChan) { | |||
return 0, os.EOF; | |||
return 0, os.EOF | |||
} | |||
var timeoutChan chan bool; | |||
@@ -78,7 +78,7 @@ func (tls *Conn) Write(p []byte) (int, os.Error) { | |||
select { | |||
case tls.writeChan <- p: | |||
case <-timeoutChan: | |||
return 0, os.EAGAIN; | |||
return 0, os.EAGAIN | |||
} | |||
return len(p), nil; | |||
@@ -148,7 +148,7 @@ type Listener struct { | |||
func (l Listener) Accept() (c net.Conn, err os.Error) { | |||
c, err = l.listener.Accept(); | |||
if err != nil { | |||
return; | |||
return | |||
} | |||
c = Server(c, l.config); | |||