138 lines
6.0 KiB
Go
138 lines
6.0 KiB
Go
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package tls
|
||
|
|
||
|
import (
|
||
|
"encoding/hex";
|
||
|
"testing";
|
||
|
"testing/script";
|
||
|
)
|
||
|
|
||
|
func setup() (appDataChan chan []byte, requestChan chan interface{}, controlChan chan interface{}, recordChan chan *record, handshakeChan chan interface{}) {
|
||
|
rp := new(recordProcessor);
|
||
|
appDataChan = make(chan []byte);
|
||
|
requestChan = make(chan interface{});
|
||
|
controlChan = make(chan interface{});
|
||
|
recordChan = make(chan *record);
|
||
|
handshakeChan = make(chan interface{});
|
||
|
|
||
|
go rp.loop(appDataChan, requestChan, controlChan, recordChan, handshakeChan);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
func fromHex(s string) []byte {
|
||
|
b, _ := hex.DecodeString(s);
|
||
|
return b;
|
||
|
}
|
||
|
|
||
|
func TestNullConnectionState(t *testing.T) {
|
||
|
_, requestChan, controlChan, recordChan, _ := setup();
|
||
|
defer close(requestChan);
|
||
|
defer close(controlChan);
|
||
|
defer close(recordChan);
|
||
|
|
||
|
// Test a simple request for the connection state.
|
||
|
replyChan := make(chan ConnectionState);
|
||
|
sendReq := script.NewEvent("send request", nil, script.Send{requestChan, getConnectionState{replyChan}});
|
||
|
getReply := script.NewEvent("get reply", []*script.Event{sendReq}, script.Recv{replyChan, ConnectionState{false, "", 0}});
|
||
|
|
||
|
err := script.Perform(0, []*script.Event{sendReq, getReply});
|
||
|
if err != nil {
|
||
|
t.Errorf("Got error: %s", err);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestWaitConnectionState(t *testing.T) {
|
||
|
_, requestChan, controlChan, recordChan, _ := setup();
|
||
|
defer close(requestChan);
|
||
|
defer close(controlChan);
|
||
|
defer close(recordChan);
|
||
|
|
||
|
// Test that waitConnectionState doesn't get a reply until the connection state changes.
|
||
|
replyChan := make(chan ConnectionState);
|
||
|
sendReq := script.NewEvent("send request", nil, script.Send{requestChan, waitConnectionState{replyChan}});
|
||
|
replyChan2 := make(chan ConnectionState);
|
||
|
sendReq2 := script.NewEvent("send request 2", []*script.Event{sendReq}, script.Send{requestChan, getConnectionState{replyChan2}});
|
||
|
getReply2 := script.NewEvent("get reply 2", []*script.Event{sendReq2}, script.Recv{replyChan2, ConnectionState{false, "", 0}});
|
||
|
sendState := script.NewEvent("send state", []*script.Event{getReply2}, script.Send{controlChan, ConnectionState{true, "test", 1}});
|
||
|
getReply := script.NewEvent("get reply", []*script.Event{sendState}, script.Recv{replyChan, ConnectionState{true, "test", 1}});
|
||
|
|
||
|
err := script.Perform(0, []*script.Event{sendReq, sendReq2, getReply2, sendState, getReply});
|
||
|
if err != nil {
|
||
|
t.Errorf("Got error: %s", err);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestHandshakeAssembly(t *testing.T) {
|
||
|
_, requestChan, controlChan, recordChan, handshakeChan := setup();
|
||
|
defer close(requestChan);
|
||
|
defer close(controlChan);
|
||
|
defer close(recordChan);
|
||
|
|
||
|
// Test the reassembly of a fragmented handshake message.
|
||
|
send1 := script.NewEvent("send 1", nil, script.Send{recordChan, &record{recordTypeHandshake, 0, 0, fromHex("10000003")}});
|
||
|
send2 := script.NewEvent("send 2", []*script.Event{send1}, script.Send{recordChan, &record{recordTypeHandshake, 0, 0, fromHex("0001")}});
|
||
|
send3 := script.NewEvent("send 3", []*script.Event{send2}, script.Send{recordChan, &record{recordTypeHandshake, 0, 0, fromHex("42")}});
|
||
|
recvMsg := script.NewEvent("recv", []*script.Event{send3}, script.Recv{handshakeChan, &clientKeyExchangeMsg{fromHex("10000003000142"), fromHex("42")}});
|
||
|
|
||
|
err := script.Perform(0, []*script.Event{send1, send2, send3, recvMsg});
|
||
|
if err != nil {
|
||
|
t.Errorf("Got error: %s", err);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestEarlyApplicationData(t *testing.T) {
|
||
|
_, requestChan, controlChan, recordChan, handshakeChan := setup();
|
||
|
defer close(requestChan);
|
||
|
defer close(controlChan);
|
||
|
defer close(recordChan);
|
||
|
|
||
|
// Test that applicaton data received before the handshake has completed results in an error.
|
||
|
send := script.NewEvent("send", nil, script.Send{recordChan, &record{recordTypeApplicationData, 0, 0, fromHex("")}});
|
||
|
recv := script.NewEvent("recv", []*script.Event{send}, script.Closed{handshakeChan});
|
||
|
|
||
|
err := script.Perform(0, []*script.Event{send, recv});
|
||
|
if err != nil {
|
||
|
t.Errorf("Got error: %s", err);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestApplicationData(t *testing.T) {
|
||
|
appDataChan, requestChan, controlChan, recordChan, handshakeChan := setup();
|
||
|
defer close(requestChan);
|
||
|
defer close(controlChan);
|
||
|
defer close(recordChan);
|
||
|
|
||
|
// Test that the application data is forwarded after a successful Finished message.
|
||
|
send1 := script.NewEvent("send 1", nil, script.Send{recordChan, &record{recordTypeHandshake, 0, 0, fromHex("1400000c000000000000000000000000")}});
|
||
|
recv1 := script.NewEvent("recv finished", []*script.Event{send1}, script.Recv{handshakeChan, &finishedMsg{fromHex("1400000c000000000000000000000000"), fromHex("000000000000000000000000")}});
|
||
|
send2 := script.NewEvent("send connState", []*script.Event{recv1}, script.Send{controlChan, ConnectionState{true, "", 0}});
|
||
|
send3 := script.NewEvent("send 2", []*script.Event{send2}, script.Send{recordChan, &record{recordTypeApplicationData, 0, 0, fromHex("0102")}});
|
||
|
recv2 := script.NewEvent("recv data", []*script.Event{send3}, script.Recv{appDataChan, []byte{0x01, 0x02}});
|
||
|
|
||
|
err := script.Perform(0, []*script.Event{send1, recv1, send2, send3, recv2});
|
||
|
if err != nil {
|
||
|
t.Errorf("Got error: %s", err);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestInvalidChangeCipherSpec(t *testing.T) {
|
||
|
appDataChan, requestChan, controlChan, recordChan, handshakeChan := setup();
|
||
|
defer close(requestChan);
|
||
|
defer close(controlChan);
|
||
|
defer close(recordChan);
|
||
|
|
||
|
send1 := script.NewEvent("send 1", nil, script.Send{recordChan, &record{recordTypeChangeCipherSpec, 0, 0, []byte{1}}});
|
||
|
recv1 := script.NewEvent("recv 1", []*script.Event{send1}, script.Recv{handshakeChan, changeCipherSpec{}});
|
||
|
send2 := script.NewEvent("send 2", []*script.Event{recv1}, script.Send{controlChan, ConnectionState{false, "", 42}});
|
||
|
close := script.NewEvent("close 1", []*script.Event{send2}, script.Closed{appDataChan});
|
||
|
close2 := script.NewEvent("close 2", []*script.Event{send2}, script.Closed{handshakeChan});
|
||
|
|
||
|
err := script.Perform(0, []*script.Event{send1, recv1, send2, close, close2});
|
||
|
if err != nil {
|
||
|
t.Errorf("Got error: %s", err);
|
||
|
}
|
||
|
}
|