Commit fe7dd553 authored by Matt Caswell's avatar Matt Caswell
Browse files

Extend the renegotiation tests



Add the ability to test both server initiated and client initiated reneg.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent 1329b952
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -38,7 +38,8 @@ The test section supports the following options
* HandshakeMode - which handshake flavour to test:
  - Simple - plain handshake (default)
  - Resume - test resumption
  - Renegotiate - test renegotiation
  - RenegotiateServer - test server initiated renegotiation
  - RenegotiateClient - test client initiated renegotiation

When HandshakeMode is Resume or Renegotiate, the original handshake is expected
to succeed. All configured test expectations are verified against the second
+57 −24
Original line number Diff line number Diff line
@@ -583,31 +583,56 @@ static void do_app_data_step(PEER *peer)
    }
}

static void do_reneg_setup_step(PEER *peer)
static void do_reneg_setup_step(const SSL_TEST_CTX *test_ctx, 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)) {
    TEST_check(test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_SERVER
                || test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_CLIENT);

    /* Check if we are the peer that is going to initiate */
    if ((test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_SERVER
                && SSL_is_server(peer->ssl))
            || (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_CLIENT
                && !SSL_is_server(peer->ssl))) {
        /*
         * If we already asked for a renegotiation then fall through to the
         * SSL_read() below.
         */
        if (!SSL_renegotiate_pending(peer->ssl)) {
            /*
             * If we are the client we will always attempt to resume the
             * session. The server may or may not resume dependant on the
             * setting of SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
             */
            if (SSL_is_server(peer->ssl))
                ret = SSL_renegotiate(peer->ssl);
            else
                ret = SSL_renegotiate_abbreviated(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
             * If status is PEER_RETRY it means we're waiting on the peer 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 status is PEER_SUCCESS then we are the server and we have
             * successfully sent the HelloRequest. We need to continue to wait
             * until the handshake arrives from the client.
             */
            if (peer->status == PEER_RETRY)
                peer->status = PEER_SUCCESS;
            else if (peer->status == PEER_SUCCESS)
                peer->status = PEER_RETRY;
            return;
        }
    }

    /*
     * The SSL object is still expecting app data, even though it's going to
@@ -616,15 +641,21 @@ static void do_reneg_setup_step(PEER *peer)
     */
    ret = SSL_read(peer->ssl, &buf, sizeof(buf));
    if (ret >= 0) {
        /* We're not actually expecting data - we're expect a reneg to start */
        /*
         * We're not actually expecting data - we're expecting 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)) {
        if (error != SSL_ERROR_WANT_READ) {
            peer->status = PEER_ERROR;
            return;
        }
        /* If we're no in init yet then we're not done with setup yet */
        if (!SSL_in_init(peer->ssl))
            return;
    }

    peer->status = PEER_SUCCESS;
@@ -678,7 +709,8 @@ static connect_phase_t next_phase(const SSL_TEST_CTX *test_ctx,
{
    switch (phase) {
    case HANDSHAKE:
        if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEGOTIATE)
        if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_SERVER
                || test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_CLIENT)
            return RENEG_APPLICATION_DATA;
        return APPLICATION_DATA;
    case RENEG_APPLICATION_DATA:
@@ -698,7 +730,8 @@ static connect_phase_t next_phase(const SSL_TEST_CTX *test_ctx,
    return -1;
}

static void do_connect_step(PEER *peer, connect_phase_t phase)
static void do_connect_step(const SSL_TEST_CTX *test_ctx, PEER *peer,
                            connect_phase_t phase)
{
    switch (phase) {
    case HANDSHAKE:
@@ -708,7 +741,7 @@ static void do_connect_step(PEER *peer, connect_phase_t phase)
        do_app_data_step(peer);
        break;
    case RENEG_SETUP:
        do_reneg_setup_step(peer);
        do_reneg_setup_step(test_ctx, peer);
        break;
    case RENEG_HANDSHAKE:
        do_handshake_step(peer);
@@ -915,11 +948,11 @@ static HANDSHAKE_RESULT *do_handshake_internal(
     */
    for(;;) {
        if (client_turn) {
            do_connect_step(&client, phase);
            do_connect_step(test_ctx, &client, phase);
            status = handshake_status(client.status, server.status,
                                      1 /* client went last */);
        } else {
            do_connect_step(&server, phase);
            do_connect_step(test_ctx, &server, phase);
            status = handshake_status(server.status, client.status,
                                      0 /* server went last */);
        }
+94 −10
Original line number Diff line number Diff line
# Generated with generate_ssl_tests.pl

num_tests = 1
num_tests = 4

test-0 = 0-renegotiate
test-0 = 0-renegotiate-client-no-resume
test-1 = 1-renegotiate-client-resume
test-2 = 2-renegotiate-server-no-resume
test-3 = 3-renegotiate-server-resume
# ===========================================================

[0-renegotiate]
ssl_conf = 0-renegotiate-ssl
[0-renegotiate-client-no-resume]
ssl_conf = 0-renegotiate-client-no-resume-ssl

[0-renegotiate-ssl]
server = 0-renegotiate-server
client = 0-renegotiate-client
[0-renegotiate-client-no-resume-ssl]
server = 0-renegotiate-client-no-resume-server
client = 0-renegotiate-client-no-resume-client

[0-renegotiate-server]
[0-renegotiate-client-no-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
Options = NoResumptionOnRenegotiation
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem

[0-renegotiate-client]
[0-renegotiate-client-no-resume-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer

[test-0]
ExpectedResult = Success
HandshakeMode = Renegotiate
HandshakeMode = RenegotiateClient
Method = TLS
ResumptionExpected = No


# ===========================================================

[1-renegotiate-client-resume]
ssl_conf = 1-renegotiate-client-resume-ssl

[1-renegotiate-client-resume-ssl]
server = 1-renegotiate-client-resume-server
client = 1-renegotiate-client-resume-client

[1-renegotiate-client-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem

[1-renegotiate-client-resume-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer

[test-1]
ExpectedResult = Success
HandshakeMode = RenegotiateClient
Method = TLS
ResumptionExpected = Yes


# ===========================================================

[2-renegotiate-server-no-resume]
ssl_conf = 2-renegotiate-server-no-resume-ssl

[2-renegotiate-server-no-resume-ssl]
server = 2-renegotiate-server-no-resume-server
client = 2-renegotiate-server-no-resume-client

[2-renegotiate-server-no-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
Options = NoResumptionOnRenegotiation
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem

[2-renegotiate-server-no-resume-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer

[test-2]
ExpectedResult = Success
HandshakeMode = RenegotiateServer
Method = TLS
ResumptionExpected = No


# ===========================================================

[3-renegotiate-server-resume]
ssl_conf = 3-renegotiate-server-resume-ssl

[3-renegotiate-server-resume-ssl]
server = 3-renegotiate-server-resume-server
client = 3-renegotiate-server-resume-client

[3-renegotiate-server-resume-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem

[3-renegotiate-server-resume-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer

[test-3]
ExpectedResult = Success
HandshakeMode = RenegotiateServer
Method = TLS
ResumptionExpected = Yes

+40 −2
Original line number Diff line number Diff line
@@ -17,12 +17,50 @@ package ssltests;

our @tests = (
    {
        name => "renegotiate",
        name => "renegotiate-client-no-resume",
        server => {
            "Options" => "NoResumptionOnRenegotiation"
        },
        client => {},
        test => {
            "Method" => "TLS",
            "HandshakeMode" => "RenegotiateClient",
            "ResumptionExpected" => "No",
            "ExpectedResult" => "Success"
        }
    },
    {
        name => "renegotiate-client-resume",
        server => {},
        client => {},
        test => {
            "Method" => "TLS",
            "HandshakeMode" => "RenegotiateClient",
            "ResumptionExpected" => "Yes",
            "ExpectedResult" => "Success"
        }
    },
    {
        name => "renegotiate-server-no-resume",
        server => {
            "Options" => "NoResumptionOnRenegotiation"
        },
        client => {},
        test => {
            "Method" => "TLS",
            "HandshakeMode" => "RenegotiateServer",
            "ResumptionExpected" => "No",
            "ExpectedResult" => "Success"
        }
    },
    {
        name => "renegotiate-server-resume",
        server => {},
        client => {},
        test => {
            "Method" => "TLS",
            "HandshakeMode" => "Renegotiate",
            "HandshakeMode" => "RenegotiateServer",
            "ResumptionExpected" => "Yes",
            "ExpectedResult" => "Success"
        }
    },
+2 −1
Original line number Diff line number Diff line
@@ -339,7 +339,8 @@ IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_alpn_protocol)
static const test_enum ssl_handshake_modes[] = {
    {"Simple", SSL_TEST_HANDSHAKE_SIMPLE},
    {"Resume", SSL_TEST_HANDSHAKE_RESUME},
    {"Renegotiate", SSL_TEST_HANDSHAKE_RENEGOTIATE},
    {"RenegotiateServer", SSL_TEST_HANDSHAKE_RENEG_SERVER},
    {"RenegotiateClient", SSL_TEST_HANDSHAKE_RENEG_CLIENT},
};

__owur static int parse_handshake_mode(SSL_TEST_CTX *test_ctx, const char *value)
Loading