summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2016-09-26 17:25:43 +0100
committerMatt Caswell <matt@openssl.org>2016-09-28 09:18:46 +0100
commitcccaf5d60b5ac37c7c300199a88a46edf6fe3fb5 (patch)
treed811a8d70afa1000e95fdc411bb8e316bd6a9c31 /test
parenta7511d72a32e13ab007f2f02fa1433965cbfe6ed (diff)
Add support for testing renegotiation
Reviewed-by: Rich Salz <rsalz@openssl.org> (cherry picked from commit e42c4544c88046a01c53a81aeb9d48685d708cf9)
Diffstat (limited to 'test')
-rw-r--r--test/handshake_helper.c77
-rw-r--r--test/recipes/80-test_ssl_new.t2
-rw-r--r--test/ssl-tests/17-renegotiate.conf30
-rw-r--r--test/ssl-tests/17-renegotiate.conf.in29
-rw-r--r--test/ssl_test_ctx.h1
5 files changed, 132 insertions, 7 deletions
diff --git a/test/handshake_helper.c b/test/handshake_helper.c
index 90e18fcaaa..dcc9d8dd22 100644
--- a/test/handshake_helper.c
+++ b/test/handshake_helper.c
@@ -583,6 +583,54 @@ static void do_app_data_step(PEER *peer)
}
}
+static void do_reneg_setup_step(PEER *peer)
+{
+ int ret;
+ char buf;
+
+ TEST_check(peer->status == PEER_RETRY);
+ /* We only support client initiated reneg at the moment */
+ /* TODO: server side */
+ if (!SSL_is_server(peer->ssl)) {
+ ret = SSL_renegotiate(peer->ssl);
+ if (!ret) {
+ peer->status = PEER_ERROR;
+ return;
+ }
+ do_handshake_step(peer);
+ /*
+ * If status is PEER_RETRY it means we're waiting on the server to
+ * continue the handshake. As far as setting up the renegotiation is
+ * concerned that is a success. The next step will continue the
+ * handshake to its conclusion.
+ */
+ if (peer->status == PEER_RETRY)
+ peer->status = PEER_SUCCESS;
+ return;
+ }
+
+ /*
+ * The SSL object is still expecting app data, even though it's going to
+ * get a handshake message. We try to read, and it should fail - after which
+ * we should be in a handshake
+ */
+ ret = SSL_read(peer->ssl, &buf, sizeof(buf));
+ if (ret >= 0) {
+ /* We're not actually expecting data - we're expect a reneg to start */
+ peer->status = PEER_ERROR;
+ return;
+ } else {
+ int error = SSL_get_error(peer->ssl, ret);
+ if (error != SSL_ERROR_WANT_READ || !SSL_in_init(peer->ssl)) {
+ peer->status = PEER_ERROR;
+ return;
+ }
+ }
+
+ peer->status = PEER_SUCCESS;
+}
+
+
/*
* RFC 5246 says:
*
@@ -617,15 +665,27 @@ static void do_shutdown_step(PEER *peer)
typedef enum {
HANDSHAKE,
+ RENEG_APPLICATION_DATA,
+ RENEG_SETUP,
+ RENEG_HANDSHAKE,
APPLICATION_DATA,
SHUTDOWN,
CONNECTION_DONE
} connect_phase_t;
-static connect_phase_t next_phase(connect_phase_t phase)
+static connect_phase_t next_phase(const SSL_TEST_CTX *test_ctx,
+ connect_phase_t phase)
{
switch (phase) {
case HANDSHAKE:
+ if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEGOTIATE)
+ return RENEG_APPLICATION_DATA;
+ return APPLICATION_DATA;
+ case RENEG_APPLICATION_DATA:
+ return RENEG_SETUP;
+ case RENEG_SETUP:
+ return RENEG_HANDSHAKE;
+ case RENEG_HANDSHAKE:
return APPLICATION_DATA;
case APPLICATION_DATA:
return SHUTDOWN;
@@ -642,6 +702,15 @@ static void do_connect_step(PEER *peer, connect_phase_t phase)
case HANDSHAKE:
do_handshake_step(peer);
break;
+ case RENEG_APPLICATION_DATA:
+ do_app_data_step(peer);
+ break;
+ case RENEG_SETUP:
+ do_reneg_setup_step(peer);
+ break;
+ case RENEG_HANDSHAKE:
+ do_handshake_step(peer);
+ break;
case APPLICATION_DATA:
do_app_data_step(peer);
break;
@@ -854,7 +923,7 @@ static HANDSHAKE_RESULT *do_handshake_internal(
switch (status) {
case HANDSHAKE_SUCCESS:
- phase = next_phase(phase);
+ phase = next_phase(test_ctx, phase);
if (phase == CONNECTION_DONE) {
ret->result = SSL_TEST_SUCCESS;
goto err;
@@ -942,11 +1011,9 @@ HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
result = do_handshake_internal(server_ctx, server2_ctx, client_ctx,
test_ctx, &test_ctx->extra,
NULL, &session);
- if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_SIMPLE)
+ if (test_ctx->handshake_mode != SSL_TEST_HANDSHAKE_RESUME)
goto end;
- TEST_check(test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME);
-
if (result->result != SSL_TEST_SUCCESS) {
result->result = SSL_TEST_FIRST_HANDSHAKE_FAILED;
goto end;
diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t
index 47eab18a95..d496f21ecd 100644
--- a/test/recipes/80-test_ssl_new.t
+++ b/test/recipes/80-test_ssl_new.t
@@ -29,7 +29,7 @@ map { s/\.in// } @conf_files;
# We hard-code the number of tests to double-check that the globbing above
# finds all files as expected.
-plan tests => 16; # = scalar @conf_srcs
+plan tests => 17; # = scalar @conf_srcs
# Some test results depend on the configuration of enabled protocols. We only
# verify generated sources in the default configuration.
diff --git a/test/ssl-tests/17-renegotiate.conf b/test/ssl-tests/17-renegotiate.conf
new file mode 100644
index 0000000000..5ef4b0ac77
--- /dev/null
+++ b/test/ssl-tests/17-renegotiate.conf
@@ -0,0 +1,30 @@
+# Generated with generate_ssl_tests.pl
+
+num_tests = 1
+
+test-0 = 0-renegotiate
+# ===========================================================
+
+[0-renegotiate]
+ssl_conf = 0-renegotiate-ssl
+
+[0-renegotiate-ssl]
+server = 0-renegotiate-server
+client = 0-renegotiate-client
+
+[0-renegotiate-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[0-renegotiate-client]
+CipherString = DEFAULT
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-0]
+ExpectedResult = Success
+HandshakeMode = Renegotiate
+Method = TLS
+
+
diff --git a/test/ssl-tests/17-renegotiate.conf.in b/test/ssl-tests/17-renegotiate.conf.in
new file mode 100644
index 0000000000..6cecd7ed21
--- /dev/null
+++ b/test/ssl-tests/17-renegotiate.conf.in
@@ -0,0 +1,29 @@
+# -*- mode: perl; -*-
+# Copyright 2016-2016 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+
+## Test Renegotiation
+
+use strict;
+use warnings;
+
+package ssltests;
+
+
+our @tests = (
+ {
+ name => "renegotiate",
+ server => {},
+ client => {},
+ test => {
+ "Method" => "TLS",
+ "HandshakeMode" => "Renegotiate",
+ "ExpectedResult" => "Success"
+ }
+ },
+);
diff --git a/test/ssl_test_ctx.h b/test/ssl_test_ctx.h
index c8c66d6d70..73e223a2d5 100644
--- a/test/ssl_test_ctx.h
+++ b/test/ssl_test_ctx.h
@@ -56,7 +56,6 @@ typedef enum {
typedef enum {
SSL_TEST_HANDSHAKE_SIMPLE = 0, /* Default */
SSL_TEST_HANDSHAKE_RESUME,
- /* Not yet implemented */
SSL_TEST_HANDSHAKE_RENEGOTIATE
} ssl_handshake_mode_t;