- 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
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
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. */
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";
# 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.
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,
"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) {
# 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 {
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;
--- /dev/null
+# 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
+
+
--- /dev/null
+# -*- 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",
+ },
+ },
+);
};
__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),
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) {
{ "ServerName", &parse_servername },
{ "NPNProtocols", &parse_client_npn_protocols },
{ "ALPNProtocols", &parse_client_alpn_protocols },
+ { "CTValidation", &parse_ct_validation },
};
/* Nested server options. */
SSL_TEST_HANDSHAKE_RENEGOTIATE
} ssl_handshake_mode_t;
+typedef enum {
+ SSL_TEST_CT_VALIDATION_NONE = 0, /* Default */
+ SSL_TEST_CT_VALIDATION_PERMISSIVE,
+ SSL_TEST_CT_VALIDATION_STRICT
+} ssl_ct_validation_t;
/*
* Server/client settings that aren't supported by the SSL CONF library,
* such as callbacks.
/* Supported NPN and ALPN protocols. A comma-separated list. */
char *npn_protocols;
char *alpn_protocols;
+ ssl_ct_validation_t ct_validation;
} SSL_TEST_CLIENT_CONF;
typedef struct {
const char *ssl_session_ticket_name(ssl_session_ticket_t server);
const char *ssl_test_method_name(ssl_test_method_t method);
const char *ssl_handshake_mode_name(ssl_handshake_mode_t mode);
+const char *ssl_ct_validation_name(ssl_ct_validation_t mode);
/*
* Load the test case context from |conf|.
if (!strings_equal("Client ALPNProtocols", client->alpn_protocols,
client2->alpn_protocols))
return 0;
+ if (client->ct_validation != client2->ct_validation) {
+ fprintf(stderr, "CTValidation mismatch: %s vs %s.\n",
+ ssl_ct_validation_name(client->ct_validation),
+ ssl_ct_validation_name(client2->ct_validation));
+ return 0;
+ }
return 1;
}
OPENSSL_assert(
fixture.expected_ctx->resume_extra.server2.alpn_protocols != NULL);
+ fixture.expected_ctx->resume_extra.client.ct_validation =
+ SSL_TEST_CT_VALIDATION_STRICT;
+
EXECUTE_SSL_TEST_CTX_TEST();
}
"ssltest_unknown_method",
"ssltest_unknown_handshake_mode",
"ssltest_unknown_resumption_expected",
+ "ssltest_unknown_ct_validation",
};
static int test_bad_configuration(int idx)
client = ssltest_good_client_extra
server = ssltest_good_server_extra
resume-server2 = ssltest_good_resume_server2_extra
+resume-client = ssltest_good_resume_client_extra
Method = DTLS
HandshakeMode = Resume
ServerName = server2
NPNProtocols = foo,bar
+[ssltest_good_resume_client_extra]
+CTValidation = Strict
+
[ssltest_good_server_extra]
ServerNameCallback = IgnoreMismatch
BrokenSessionTicket = Yes
[ssltest_unknown_resumption_expected]
ResumptionExpected = Foo
+
+[ssltest_unknown_ct_validation]
+client = ssltest_unknown_ct_validation_client
+
+[ssltest_unknown_ct_validation_client]
+CTCallback = Foo