Add support for testing renegotiation
Reviewed-by: Rich Salz <rsalz@openssl.org>
This commit is contained in:
parent
2f97192c78
commit
e42c4544c8
5 changed files with 132 additions and 7 deletions
|
@ -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;
|
||||
|
@ -644,6 +704,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;
|
||||
|
@ -857,7 +926,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;
|
||||
|
@ -945,11 +1014,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;
|
||||
|
|
|
@ -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.
|
||||
|
|
30
test/ssl-tests/17-renegotiate.conf
Normal file
30
test/ssl-tests/17-renegotiate.conf
Normal file
|
@ -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
|
||||
|
||||
|
29
test/ssl-tests/17-renegotiate.conf.in
Normal file
29
test/ssl-tests/17-renegotiate.conf.in
Normal file
|
@ -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"
|
||||
}
|
||||
},
|
||||
);
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue