Kaynağa Gözat

Add some basic server tests to runner.go.

client_shim.cc and runner.go are generalized to handle both ends. Plumb a bit
through the test case to control which and add server versions of all the
cipher suite tests.

Change-Id: Iab2640b390f7ed7160c9a9bf6bb34b8bec761b2e
Reviewed-on: https://boringssl-review.googlesource.com/1091
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin 10 yıl önce
committed by Adam Langley
ebeveyn
işleme
025b3d3459
4 değiştirilmiş dosya ile 274 ekleme ve 151 silme
  1. +3
    -3
      ssl/test/CMakeLists.txt
  2. +164
    -0
      ssl/test/bssl_shim.cc
  3. +0
    -118
      ssl/test/client_shim.cc
  4. +107
    -30
      ssl/test/runner/runner.go

+ 3
- 3
ssl/test/CMakeLists.txt Dosyayı Görüntüle

@@ -1,9 +1,9 @@
include_directories(../../include)

add_executable(
client_shim
bssl_shim

client_shim.cc
bssl_shim.cc
)

target_link_libraries(client_shim ssl crypto)
target_link_libraries(bssl_shim ssl crypto)

+ 164
- 0
ssl/test/bssl_shim.cc Dosyayı Görüntüle

@@ -0,0 +1,164 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <openssl/ssl.h>
#include <openssl/bio.h>


SSL *setup_test(int is_server) {
if (!SSL_library_init()) {
return NULL;
}

SSL_CTX *ssl_ctx = NULL;
SSL *ssl = NULL;
BIO *bio = NULL;

ssl_ctx = SSL_CTX_new(
is_server ? SSLv23_server_method() : SSLv23_client_method());
if (ssl_ctx == NULL) {
goto err;
}

if (!SSL_CTX_set_ecdh_auto(ssl_ctx, 1)) {
goto err;
}

if (!SSL_CTX_set_cipher_list(ssl_ctx, "ALL")) {
goto err;
}

ssl = SSL_new(ssl_ctx);
if (ssl == NULL) {
goto err;
}

bio = BIO_new_fd(3, 1 /* take ownership */);
if (bio == NULL) {
goto err;
}

SSL_set_bio(ssl, bio, bio);
SSL_CTX_free(ssl_ctx);

return ssl;

err:
if (bio != NULL) {
BIO_free(bio);
}
if (ssl != NULL) {
SSL_free(ssl);
}
if (ssl_ctx != NULL) {
SSL_CTX_free(ssl_ctx);
}
return NULL;
}

int main(int argc, char **argv) {
int i, is_server, ret;

if (argc < 2) {
fprintf(stderr, "Usage: %s (client|server) [flags...]\n", argv[0]);
return 1;
}
if (strcmp(argv[1], "client") == 0) {
is_server = 0;
} else if (strcmp(argv[1], "server") == 0) {
is_server = 1;
} else {
fprintf(stderr, "Usage: %s (client|server) [flags...]\n", argv[0]);
return 1;
}

SSL *ssl = setup_test(is_server);
if (ssl == NULL) {
BIO_print_errors_fp(stdout);
return 1;
}

for (i = 2; i < argc; i++) {
if (strcmp(argv[i], "-fallback-scsv") == 0) {
if (!SSL_enable_fallback_scsv(ssl)) {
BIO_print_errors_fp(stdout);
return 1;
}
} else if (strcmp(argv[i], "-key-file") == 0) {
i++;
if (i >= argc) {
fprintf(stderr, "Missing parameter\n");
return 1;
}
if (!SSL_use_PrivateKey_file(ssl, argv[i], SSL_FILETYPE_PEM)) {
BIO_print_errors_fp(stdout);
return 1;
}
} else if (strcmp(argv[i], "-cert-file") == 0) {
i++;
if (i >= argc) {
fprintf(stderr, "Missing parameter\n");
return 1;
}
if (!SSL_use_certificate_file(ssl, argv[i], SSL_FILETYPE_PEM)) {
BIO_print_errors_fp(stdout);
return 1;
}
} else {
fprintf(stderr, "Unknown argument: %s\n", argv[i]);
return 1;
}
}

if (is_server) {
ret = SSL_accept(ssl);
} else {
ret = SSL_connect(ssl);
}
if (ret != 1) {
SSL_free(ssl);
BIO_print_errors_fp(stdout);
return 2;
}

for (;;) {
uint8_t buf[512];
int n = SSL_read(ssl, buf, sizeof(buf));
if (n < 0) {
SSL_free(ssl);
BIO_print_errors_fp(stdout);
return 3;
} else if (n == 0) {
break;
} else {
for (int i = 0; i < n; i++) {
buf[i] ^= 0xff;
}
int w = SSL_write(ssl, buf, n);
if (w != n) {
SSL_free(ssl);
BIO_print_errors_fp(stdout);
return 4;
}
}
}

SSL_free(ssl);
return 0;
}

+ 0
- 118
ssl/test/client_shim.cc Dosyayı Görüntüle

@@ -1,118 +0,0 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <openssl/ssl.h>
#include <openssl/bio.h>


SSL *setup_test() {
if (!SSL_library_init()) {
return NULL;
}

SSL_CTX *client_ctx = NULL;
SSL *client = NULL;
BIO *bio = NULL;

client_ctx = SSL_CTX_new(SSLv23_client_method());
if (client_ctx == NULL) {
goto err;
}

if (!SSL_CTX_set_cipher_list(client_ctx, "ALL")) {
goto err;
}

client = SSL_new(client_ctx);
if (client == NULL) {
goto err;
}

bio = BIO_new_fd(3, 1 /* take ownership */);
if (bio == NULL) {
goto err;
}

SSL_set_bio(client, bio, bio);
SSL_CTX_free(client_ctx);

return client;

err:
if (bio != NULL) {
BIO_free(bio);
}
if (client != NULL) {
SSL_free(client);
}
if (client_ctx != NULL) {
SSL_CTX_free(client_ctx);
}
return NULL;
}

int main(int argc, char **argv) {
int i;

SSL *client = setup_test();
if (client == NULL) {
BIO_print_errors_fp(stdout);
return 1;
}

for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-fallback-scsv") == 0) {
SSL_enable_fallback_scsv(client);
} else {
fprintf(stderr, "Unknown argument: %s\n", argv[i]);
return 1;
}
}

if (SSL_connect(client) != 1) {
SSL_free(client);
BIO_print_errors_fp(stdout);
return 2;
}

for (;;) {
uint8_t buf[512];
int n = SSL_read(client, buf, sizeof(buf));
if (n < 0) {
SSL_free(client);
BIO_print_errors_fp(stdout);
return 3;
} else if (n == 0) {
break;
} else {
for (int i = 0; i < n; i++) {
buf[i] ^= 0xff;
}
int w = SSL_write(client, buf, n);
if (w != n) {
SSL_free(client);
BIO_print_errors_fp(stdout);
return 4;
}
}
}

SSL_free(client);
return 0;
}

+ 107
- 30
ssl/test/runner/runner.go Dosyayı Görüntüle

@@ -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 clientTests = []testCase{
var testCases = []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{shimEnd}
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()
shimEnd.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++ {
clientTests = append(clientTests, testCase{
testCases = append(testCases, 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() {
clientTests = append(clientTests, testCase{
testCases = append(testCases, 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
})
clientTests = append(clientTests, testCase{
testCases = append(testCases, 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.
clientTests = append(clientTests, testCase{
testCases = append(testCases, 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(clientTests))
go statusPrinter(doneChan, statusChan, len(testCases))

for i := 0; i < numWorkers; i++ {
wg.Add(1)
go worker(statusChan, testChan, &wg)
}

for i := range clientTests {
if len(*flagTest) == 0 || *flagTest == clientTests[i].name {
testChan <- &clientTests[i]
for i := range testCases {
if len(*flagTest) == 0 || *flagTest == testCases[i].name {
testChan <- &testCases[i]
}
}



Yükleniyor…
İptal
Kaydet