@@ -15,16 +15,26 @@ import (
var useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
const (
rsaCertificateFile = "cert.pem"
ecdsaCertificateFile = "ecdsa_cert.pem"
)
const (
rsaKeyFile = "key.pem"
ecdsaKeyFile = "ecdsa_key.pem"
)
var rsaCertificate, ecdsaCertificate Certificate
func initCertificates() {
var err error
rsaCertificate, err = LoadX509KeyPair("cert.pem", "key.pem")
rsaCertificate, err = LoadX509KeyPair(rsaCertificateFile, rsaKeyFile )
if err != nil {
panic(err)
}
ecdsaCertificate, err = LoadX509KeyPair("ecdsa_cert.pem", "ecdsa_key.pem")
ecdsaCertificate, err = LoadX509KeyPair(ecdsaCertificateFile, ecdsaKeyFile )
if err != nil {
panic(err)
}
@@ -42,7 +52,15 @@ func getECDSACertificate() Certificate {
return ecdsaCertificate
}
type testType int
const (
clientTest testType = iota
serverTest
)
type testCase struct {
testType testType
name string
config Config
shouldFail bool
@@ -53,12 +71,16 @@ type testCase struct {
// messageLen is the length, in bytes, of the test message that will be
// sent.
messageLen int
// certFile is the path to the certificate to use for the server.
certFile string
// keyFile is the path to the private key to use for the server.
keyFile string
// flags, if not empty, contains a list of command-line flags that will
// be passed to the shim program.
flags []string
}
var clien tT ests = []testCase{
var testCase s = []testCase{
{
name: "BadRSASignature",
config: Config{
@@ -170,7 +192,7 @@ func runTest(test *testCase) error {
syscall.CloseOnExec(socks[0])
syscall.CloseOnExec(socks[1])
clientEnd := os.NewFile(uintptr(socks[0]), "client end")
shimEnd := os.NewFile(uintptr(socks[0]), "shim end")
connFile := os.NewFile(uintptr(socks[1]), "our end")
conn, err := net.FileConn(connFile)
connFile.Close()
@@ -178,35 +200,63 @@ func runTest(test *testCase) error {
panic(err)
}
const shim_path = "../../../build/ssl/test/client_shim"
var client *exec.Cmd
const shim_path = "../../../build/ssl/test/bssl_shim"
flags := []string{}
if test.testType == clientTest {
flags = append(flags, "client")
} else {
flags = append(flags, "server")
flags = append(flags, "-key-file")
if test.keyFile == "" {
flags = append(flags, rsaKeyFile)
} else {
flags = append(flags, test.keyFile)
}
flags = append(flags, "-cert-file")
if test.certFile == "" {
flags = append(flags, rsaCertificateFile)
} else {
flags = append(flags, test.certFile)
}
}
flags = append(flags, test.flags...)
var shim *exec.Cmd
if *useValgrind {
client = valgrindOf(false, shim_path, test.flags...)
shim = valgrindOf(false, shim_path, flags...)
} else {
client = exec.Command(shim_path, test.flags...)
shim = exec.Command(shim_path, flags...)
}
//client := gdbOf(shim_path)
client.ExtraFiles = []*os.File{clientEnd}
client.Stdin = os.Stdin
// shim = gdbOf(shim_path, flags... )
shim.ExtraFiles = []*os.File{shim End}
shim .Stdin = os.Stdin
var stdoutBuf, stderrBuf bytes.Buffer
client.Stdout = &stdoutBuf
client.Stderr = &stderrBuf
shim .Stdout = &stdoutBuf
shim .Stderr = &stderrBuf
if err := client.Start(); err != nil {
if err := shim .Start(); err != nil {
panic(err)
}
clientEnd.Close()
shim End.Close()
config := test.config
if len(config.Certificates) == 0 {
config.Certificates = []Certificate{getRSACertificate()}
}
tlsConn := Server(conn, &config)
var tlsConn *Conn
if test.testType == clientTest {
if len(config.Certificates) == 0 {
config.Certificates = []Certificate{getRSACertificate()}
}
tlsConn = Server(conn, &config)
} else {
config.InsecureSkipVerify = true
tlsConn = Client(conn, &config)
}
err = doExchange(tlsConn, test.messageLen)
conn.Close()
childErr := client.Wait()
childErr := shim .Wait()
stdout := string(stdoutBuf.Bytes())
stderr := string(stderrBuf.Bytes())
@@ -282,10 +332,16 @@ var testCipherSuites = []struct {
func addCipherSuiteTests() {
for _, suite := range testCipherSuites {
var cert Certificate
var certFile string
var keyFile string
if strings.Contains(suite.name, "ECDSA") {
cert = getECDSACertificate()
certFile = ecdsaCertificateFile
keyFile = ecdsaKeyFile
} else {
cert = getRSACertificate()
certFile = rsaCertificateFile
keyFile = rsaKeyFile
}
for _, ver := range tlsVersions {
@@ -293,8 +349,9 @@ func addCipherSuiteTests() {
continue
}
clientTests = append(clientTests, testCase{
name: ver.name + "-" + suite.name,
testCases = append(testCases, testCase{
testType: clientTest,
name: ver.name + "-" + suite.name + "-client",
config: Config{
MinVersion: ver.version,
MaxVersion: ver.version,
@@ -302,6 +359,26 @@ func addCipherSuiteTests() {
Certificates: []Certificate{cert},
},
})
// Go's TLS implementation implements SSLv3 as a server,
// but not as a client.
//
// TODO(davidben): Implement SSLv3 as a client too to
// exercise that code.
if ver.version != VersionSSL30 {
testCases = append(testCases, testCase{
testType: serverTest,
name: ver.name + "-" + suite.name + "-server",
config: Config{
MinVersion: ver.version,
MaxVersion: ver.version,
CipherSuites: []uint16{suite.id},
Certificates: []Certificate{cert},
},
certFile: certFile,
keyFile: keyFile,
})
}
}
}
}
@@ -309,7 +386,7 @@ func addCipherSuiteTests() {
func addBadECDSASignatureTests() {
for badR := BadValue(1); badR < NumBadValues; badR++ {
for badS := BadValue(1); badS < NumBadValues; badS++ {
clien tT ests = append(clien tT ests, testCase{
testCase s = append(testCase s, testCase{
name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS),
config: Config{
CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
@@ -327,7 +404,7 @@ func addBadECDSASignatureTests() {
}
func addCBCPaddingTests() {
clien tT ests = append(clien tT ests, testCase{
testCase s = append(testCase s, testCase{
name: "MaxCBCPadding",
config: Config{
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
@@ -337,7 +414,7 @@ func addCBCPaddingTests() {
},
messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
})
clien tT ests = append(clien tT ests, testCase{
testCase s = append(testCase s, testCase{
name: "BadCBCPadding",
config: Config{
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
@@ -350,7 +427,7 @@ func addCBCPaddingTests() {
})
// OpenSSL previously had an issue where the first byte of padding in
// 255 bytes of padding wasn't checked.
clien tT ests = append(clien tT ests, testCase{
testCase s = append(testCase s, testCase{
name: "BadCBCPadding255",
config: Config{
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
@@ -421,16 +498,16 @@ func main() {
testChan := make(chan *testCase, numWorkers)
doneChan := make(chan struct{})
go statusPrinter(doneChan, statusChan, len(clien tT ests))
go statusPrinter(doneChan, statusChan, len(testCase s))
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go worker(statusChan, testChan, &wg)
}
for i := range clien tT ests {
if len(*flagTest) == 0 || *flagTest == clien tT ests[i].name {
testChan <- &clien tT ests[i]
for i := range testCase s {
if len(*flagTest) == 0 || *flagTest == testCase s[i].name {
testChan <- &testCase s[i]
}
}