Skip to content

Commit

Permalink
SSL tests: port CT tests, add a few more
Browse files Browse the repository at this point in the history
This commit only ports existing tests, and adds some coverage for
resumption. We don't appear to have any handshake tests that cover SCT
validation success, and this commit doesn't change that.

Reviewed-by: Rich Salz <[email protected]>
  • Loading branch information
ekasper committed Aug 10, 2016
1 parent b03fe23 commit da085d2
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 25 deletions.
9 changes: 9 additions & 0 deletions test/README.ssltest.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ client => {
- server2 - the secondary context
- invalid - an unknown context

* CTValidation - Certificate Transparency validation strategy. One of
- None - no validation (default)
- Permissive - SSL_CT_VALIDATION_PERMISSIVE
- Strict - SSL_CT_VALIDATION_STRICT

#### Supported server-side options

* ServerNameCallback - the SNI switching callback to use
Expand Down Expand Up @@ -212,6 +217,10 @@ $ TEST_CERTS_DIR=test/certs util/shlib_wrap.sh test/ssl_test \
test/ssl-tests/01-simple.conf
```

Some tests also need additional environment variables; for example, Certificate
Transparency tests need a `CTLOG_FILE`. See `test/recipes/80-test_ssl_new.t` for
details.

Note that the test expectations sometimes depend on the Configure settings. For
example, the negotiated protocol depends on the set of available (enabled)
protocols: a build with `enable-ssl3` has different test expectations than a
Expand Down
16 changes: 16 additions & 0 deletions test/handshake_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,22 @@ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
OPENSSL_assert(SSL_CTX_set_tlsext_ticket_keys(server_ctx, ticket_keys,
ticket_key_len) == 1);
OPENSSL_free(ticket_keys);

#ifndef OPENSSL_NO_CT
OPENSSL_assert(SSL_CTX_set_default_ctlog_list_file(client_ctx));
switch (extra->client.ct_validation) {
case SSL_TEST_CT_VALIDATION_PERMISSIVE:
OPENSSL_assert(SSL_CTX_enable_ct(client_ctx,
SSL_CT_VALIDATION_PERMISSIVE));
break;
case SSL_TEST_CT_VALIDATION_STRICT:
OPENSSL_assert(SSL_CTX_enable_ct(client_ctx,
SSL_CT_VALIDATION_STRICT));
break;
case SSL_TEST_CT_VALIDATION_NONE:
break;
}
#endif
}

/* Configure per-SSL callbacks and other properties. */
Expand Down
5 changes: 4 additions & 1 deletion test/recipes/80-test_ssl_new.t
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use OpenSSL::Test::Utils qw/disabled alldisabled available_protocols/;
setup("test_ssl_new");

$ENV{TEST_CERTS_DIR} = srctop_dir("test", "certs");
$ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf");

my @conf_srcs = glob(srctop_file("test", "ssl-tests", "*.conf.in"));
map { s/;.*// } @conf_srcs if $^O eq "VMS";
Expand All @@ -28,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 => 11; # = scalar @conf_srcs
plan tests => 12; # = scalar @conf_srcs

# Some test results depend on the configuration of enabled protocols. We only
# verify generated sources in the default configuration.
Expand All @@ -40,6 +41,7 @@ my $is_default_dtls = (!disabled("dtls1") && !disabled("dtls1_2"));
my $no_tls = alldisabled(available_protocols("tls"));
my $no_dtls = alldisabled(available_protocols("dtls"));
my $no_npn = disabled("nextprotoneg");
my $no_ct = disabled("ct");

my %conf_dependent_tests = (
"02-protocol-version.conf" => !$is_default_tls,
Expand All @@ -55,6 +57,7 @@ my %skip = (
"08-npn.conf" => $no_tls || $no_npn,
"10-resumption.conf" => disabled("tls1_1") || disabled("tls1_2"),
"11-dtls_resumption.conf" => disabled("dtls1") || disabled("dtls1_2"),
"12-ct.conf" => $no_tls || $no_ct,
);

foreach my $conf (@conf_files) {
Expand Down
24 changes: 1 addition & 23 deletions test/recipes/80-test_ssl_old.t
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ my $client_sess="client.ss";
# new format in ssl_test.c and add recipes to 80-test_ssl_new.t instead.
plan tests =>
1 # For testss
+8 # For the first testssl
+7 # For the first testssl
;

subtest 'test_ss' => sub {
Expand Down Expand Up @@ -601,28 +601,6 @@ sub testssl {
ok(run(test([@ssltest, "-cipher", "AES128-SHA256", "-bytes", "8m"])));
}
};

subtest 'Certificate Transparency tests' => sub {
######################################################################

plan tests => 3;

SKIP: {
skip "Certificate Transparency is not supported by this OpenSSL build", 3
if $no_ct;
skip "TLSv1.0 is not supported by this OpenSSL build", 3
if $no_tls1;

$ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf");
my @ca = qw(-CAfile certCA.ss);
ok(run(test([@ssltest, @ca, "-bio_pair", "-tls1", "-noct"])));
# No SCTs provided, so this should fail.
ok(run(test([@ssltest, @ca, "-bio_pair", "-tls1", "-ct",
"-should_negotiate", "fail-client"])));
# No SCTs provided, unverified chains still succeed.
ok(run(test([@ssltest, "-bio_pair", "-tls1", "-ct"])));
}
};
}

unlink $CAkey;
Expand Down
135 changes: 135 additions & 0 deletions test/ssl-tests/12-ct.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Generated with generate_ssl_tests.pl

num_tests = 4

test-0 = 0-ct-permissive
test-1 = 1-ct-strict
test-2 = 2-ct-permissive-resumption
test-3 = 3-ct-strict-resumption
# ===========================================================

[0-ct-permissive]
ssl_conf = 0-ct-permissive-ssl

[0-ct-permissive-ssl]
server = 0-ct-permissive-server
client = 0-ct-permissive-client

[0-ct-permissive-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem

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

[test-0]
ExpectedResult = Success
client = 0-ct-permissive-client-extra

[0-ct-permissive-client-extra]
CTValidation = Permissive


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

[1-ct-strict]
ssl_conf = 1-ct-strict-ssl

[1-ct-strict-ssl]
server = 1-ct-strict-server
client = 1-ct-strict-client

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

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

[test-1]
ExpectedClientAlert = HandshakeFailure
ExpectedResult = ClientFail
client = 1-ct-strict-client-extra

[1-ct-strict-client-extra]
CTValidation = Strict


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

[2-ct-permissive-resumption]
ssl_conf = 2-ct-permissive-resumption-ssl

[2-ct-permissive-resumption-ssl]
server = 2-ct-permissive-resumption-server
client = 2-ct-permissive-resumption-client
resume-server = 2-ct-permissive-resumption-server
resume-client = 2-ct-permissive-resumption-client

[2-ct-permissive-resumption-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem

[2-ct-permissive-resumption-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer

[test-2]
ExpectedResult = Success
HandshakeMode = Resume
ResumptionExpected = Yes
client = 2-ct-permissive-resumption-client-extra
resume-client = 2-ct-permissive-resumption-client-extra

[2-ct-permissive-resumption-client-extra]
CTValidation = Permissive


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

[3-ct-strict-resumption]
ssl_conf = 3-ct-strict-resumption-ssl

[3-ct-strict-resumption-ssl]
server = 3-ct-strict-resumption-server
client = 3-ct-strict-resumption-client
resume-server = 3-ct-strict-resumption-server
resume-client = 3-ct-strict-resumption-resume-client

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

[3-ct-strict-resumption-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer

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

[test-3]
ExpectedResult = Success
HandshakeMode = Resume
ResumptionExpected = Yes
client = 3-ct-strict-resumption-client-extra
resume-client = 3-ct-strict-resumption-resume-client-extra

[3-ct-strict-resumption-client-extra]
CTValidation = Permissive

[3-ct-strict-resumption-resume-client-extra]
CTValidation = Strict


80 changes: 80 additions & 0 deletions test/ssl-tests/12-ct.conf.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# -*- 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 version negotiation

use strict;
use warnings;

package ssltests;


our @tests = (
# Currently only have tests for certs without SCTs.
{
name => "ct-permissive",
server => { },
client => {
extra => {
"CTValidation" => "Permissive",
},
},
test => {
"ExpectedResult" => "Success",
},
},
{
name => "ct-strict",
server => { },
client => {
extra => {
"CTValidation" => "Strict",
},
},
test => {
"ExpectedResult" => "ClientFail",
"ExpectedClientAlert" => "HandshakeFailure",
},
},
{
name => "ct-permissive-resumption",
server => { },
client => {
extra => {
"CTValidation" => "Permissive",
},
},
test => {
"HandshakeMode" => "Resume",
"ResumptionExpected" => "Yes",
"ExpectedResult" => "Success",
},
},
{
name => "ct-strict-resumption",
server => { },
client => {
extra => {
"CTValidation" => "Permissive",
},
},
# SCTs are not present during resumption, so the resumption
# should succeed.
resume_client => {
extra => {
"CTValidation" => "Strict",
},
},
test => {
"HandshakeMode" => "Resume",
"ResumptionExpected" => "Yes",
"ExpectedResult" => "Success",
},
},
);
31 changes: 30 additions & 1 deletion test/ssl_test_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static const test_enum ssl_verify_callbacks[] = {
};

__owur static int parse_client_verify_callback(SSL_TEST_CLIENT_CONF *client_conf,
const char *value)
const char *value)
{
int ret_value;
if (!parse_enum(ssl_verify_callbacks, OSSL_NELEM(ssl_verify_callbacks),
Expand Down Expand Up @@ -328,6 +328,34 @@ const char *ssl_handshake_mode_name(ssl_handshake_mode_t mode)
mode);
}

/***********************/
/* CT Validation */
/***********************/

static const test_enum ssl_ct_validation_modes[] = {
{"None", SSL_TEST_CT_VALIDATION_NONE},
{"Permissive", SSL_TEST_CT_VALIDATION_PERMISSIVE},
{"Strict", SSL_TEST_CT_VALIDATION_STRICT},
};

__owur static int parse_ct_validation(SSL_TEST_CLIENT_CONF *client_conf,
const char *value)
{
int ret_value;
if (!parse_enum(ssl_ct_validation_modes, OSSL_NELEM(ssl_ct_validation_modes),
&ret_value, value)) {
return 0;
}
client_conf->ct_validation = ret_value;
return 1;
}

const char *ssl_ct_validation_name(ssl_ct_validation_t mode)
{
return enum_name(ssl_ct_validation_modes, OSSL_NELEM(ssl_ct_validation_modes),
mode);
}

static int parse_boolean(const char *value, int *result)
{
if (strcasecmp(value, "Yes") == 0) {
Expand Down Expand Up @@ -385,6 +413,7 @@ static const ssl_test_client_option ssl_test_client_options[] = {
{ "ServerName", &parse_servername },
{ "NPNProtocols", &parse_client_npn_protocols },
{ "ALPNProtocols", &parse_client_alpn_protocols },
{ "CTValidation", &parse_ct_validation },
};

/* Nested server options. */
Expand Down
Loading

0 comments on commit da085d2

Please sign in to comment.