[openssl-commits] [openssl] master update

Emilia Kasper emilia at openssl.org
Wed Aug 10 12:41:28 UTC 2016


The branch master has been updated
       via  2f35e6a3eb327b9ada5da06fb914df566da81f94 (commit)
       via  d61f00780a232659161ac08847cd787af8672845 (commit)
       via  da085d273c6f2a82f3e13dc6482e0f00e0daab5b (commit)
       via  b03fe23146a7ef6047226fa4927103b80e8fe155 (commit)
       via  6bd3379a5831530d41fb2eebe8ec020bb917a621 (commit)
      from  eb633d03fe2db3666840dee8d0a2dbe491672dfc (commit)


- Log -----------------------------------------------------------------
commit 2f35e6a3eb327b9ada5da06fb914df566da81f94
Author: Emilia Kasper <emilia at openssl.org>
Date:   Tue Aug 9 17:08:59 2016 +0200

    Gracefully free a NULL HANDSHAKE_RESULT
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit d61f00780a232659161ac08847cd787af8672845
Author: Emilia Kasper <emilia at openssl.org>
Date:   Tue Aug 9 17:03:23 2016 +0200

    Add TEST_check
    
    Like OPENSSL_assert, but also prints the error stack before exiting.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit da085d273c6f2a82f3e13dc6482e0f00e0daab5b
Author: Emilia Kasper <emilia at openssl.org>
Date:   Tue Aug 9 16:47:26 2016 +0200

    SSL tests: port CT tests, add a few more
    
    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 <rsalz at openssl.org>

commit b03fe23146a7ef6047226fa4927103b80e8fe155
Author: Emilia Kasper <emilia at openssl.org>
Date:   Tue Aug 9 16:46:27 2016 +0200

    CT: fix documentation
    
    Make method names match reality
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 6bd3379a5831530d41fb2eebe8ec020bb917a621
Author: Emilia Kasper <emilia at openssl.org>
Date:   Tue Aug 9 14:55:33 2016 +0200

    SSL test ctx: fix tests
    
    Some failure tests were failing for the wrong reason after the CTX
    refactoring. Update those tests.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 doc/ssl/SSL_CTX_set_ct_validation_callback.pod |  18 ++--
 test/README.ssltest.md                         |   9 ++
 test/handshake_helper.c                        |  72 ++++++++-----
 test/recipes/80-test_ssl_new.t                 |   5 +-
 test/recipes/80-test_ssl_old.t                 |  24 +----
 test/ssl-tests/12-ct.conf                      | 135 +++++++++++++++++++++++++
 test/ssl-tests/12-ct.conf.in                   |  80 +++++++++++++++
 test/ssl_test.c                                |  24 ++---
 test/ssl_test_ctx.c                            |  46 +++++++--
 test/ssl_test_ctx.h                            |   7 ++
 test/ssl_test_ctx_test.c                       |  22 ++--
 test/ssl_test_ctx_test.conf                    |  29 +++++-
 test/testutil.h                                |  15 +++
 13 files changed, 397 insertions(+), 89 deletions(-)
 create mode 100644 test/ssl-tests/12-ct.conf
 create mode 100644 test/ssl-tests/12-ct.conf.in

diff --git a/doc/ssl/SSL_CTX_set_ct_validation_callback.pod b/doc/ssl/SSL_CTX_set_ct_validation_callback.pod
index 2ff33f7..036ed03 100644
--- a/doc/ssl/SSL_CTX_set_ct_validation_callback.pod
+++ b/doc/ssl/SSL_CTX_set_ct_validation_callback.pod
@@ -11,21 +11,21 @@ control Certificate Transparency policy
 
  #include <openssl/ssl.h>
 
- int SSL_ct_enable(SSL *s, int validation_mode);
- int SSL_CTX_ct_enable(SSL_CTX *ctx, int validation_mode);
+ int SSL_enable_ct(SSL *s, int validation_mode);
+ int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode);
  int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback,
                                     void *arg);
  int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx,
                                         ssl_ct_validation_cb callback,
                                         void *arg);
- void SSL_ct_disable(SSL *s);
- void SSL_CTX_ct_disable(SSL_CTX *ctx);
+ void SSL_disable_ct(SSL *s);
+ void SSL_CTX_disable_ct(SSL_CTX *ctx);
  int SSL_ct_is_enabled(const SSL *s);
  int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx);
 
 =head1 DESCRIPTION
 
-SSL_ct_enable() and SSL_CTX_ct_enable() enable the processing of signed
+SSL_enable_ct() and SSL_CTX_enable_ct() enable the processing of signed
 certificate timestamps (SCTs) either for a given SSL connection or for all
 connections that share the given SSL context, respectively.
 This is accomplished by setting a built-in CT validation callback.
@@ -84,12 +84,12 @@ Clients that require SCTs are expected to not have enabled any aNULL ciphers
 nor to have specified server verification via DANE-TA(2) or DANE-EE(3) TLSA
 records.
 
-SSL_ct_disable() and SSL_CTX_ct_disable() turn off CT processing, whether
+SSL_disable_ct() and SSL_CTX_disable_ct() turn off CT processing, whether
 enabled via the built-in or the custom callbacks, by setting a NULL callback.
 These may be implemented as macros.
 
 SSL_ct_is_enabled() and SSL_CTX_ct_is_enabled() return 1 if CT processing is
-enabled via either SSL_ct_enable() or a non-null custom callback, and 0
+enabled via either SSL_enable_ct() or a non-null custom callback, and 0
 otherwise.
 
 =head1 NOTES
@@ -105,13 +105,13 @@ extensions (B<TLSEXT_TYPE_signed_certificate_timestamp>).
 
 =head1 RETURN VALUES
 
-SSL_ct_enable(), SSL_CTX_ct_enable(), SSL_CTX_set_ct_validation_callback() and
+SSL_enable_ct(), SSL_CTX_enable_ct(), SSL_CTX_set_ct_validation_callback() and
 SSL_set_ct_validation_callback() return 1 if the B<callback> is successfully
 set.
 They return 0 if an error occurs, e.g. a custom client extension handler has
 been setup to handle SCTs.
 
-SSL_ct_disable() and SSL_CTX_ct_disable() do not return a result.
+SSL_disable_ct() and SSL_CTX_disable_ct() do not return a result.
 
 SSL_CTX_ct_is_enabled() and SSL_ct_is_enabled() return a 1 if a non-null CT
 validation callback is set, or 0 if no callback (or equivalently a NULL
diff --git a/test/README.ssltest.md b/test/README.ssltest.md
index 53ee0b4..d6b020d 100644
--- a/test/README.ssltest.md
+++ b/test/README.ssltest.md
@@ -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
@@ -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
diff --git a/test/handshake_helper.c b/test/handshake_helper.c
index be689dc..3e7f129 100644
--- a/test/handshake_helper.c
+++ b/test/handshake_helper.c
@@ -14,17 +14,19 @@
 #include <openssl/ssl.h>
 
 #include "handshake_helper.h"
+#include "testutil.h"
 
 HANDSHAKE_RESULT *HANDSHAKE_RESULT_new()
 {
-    HANDSHAKE_RESULT *ret;
-    ret = OPENSSL_zalloc(sizeof(*ret));
-    OPENSSL_assert(ret != NULL);
+    HANDSHAKE_RESULT *ret = OPENSSL_zalloc(sizeof(*ret));
+    TEST_check(ret != NULL);
     return ret;
 }
 
 void HANDSHAKE_RESULT_free(HANDSHAKE_RESULT *result)
 {
+    if (result == NULL)
+        return;
     OPENSSL_free(result->client_npn_negotiated);
     OPENSSL_free(result->server_npn_negotiated);
     OPENSSL_free(result->client_alpn_negotiated);
@@ -172,11 +174,11 @@ static void parse_protos(const char *protos, unsigned char **out, size_t *outlen
     len = strlen(protos);
 
     /* Should never have reuse. */
-    OPENSSL_assert(*out == NULL);
+    TEST_check(*out == NULL);
 
     /* Test values are small, so we omit length limit checks. */
     *out = OPENSSL_malloc(len + 1);
-    OPENSSL_assert(*out != NULL);
+    TEST_check(*out != NULL);
     *outlen = len + 1;
 
     /*
@@ -189,13 +191,13 @@ static void parse_protos(const char *protos, unsigned char **out, size_t *outlen
     i = prefix + 1;
     while (i <= len) {
         if ((*out)[i] == ',') {
-            OPENSSL_assert(i - 1 - prefix > 0);
+            TEST_check(i - 1 - prefix > 0);
             (*out)[prefix] = i - 1 - prefix;
             prefix = i;
         }
         i++;
     }
-    OPENSSL_assert(len - prefix > 0);
+    TEST_check(len - prefix > 0);
     (*out)[prefix] = len - prefix;
 }
 
@@ -217,8 +219,7 @@ static int client_npn_cb(SSL *s, unsigned char **out, unsigned char *outlen,
                                 ctx_data->npn_protocols,
                                 ctx_data->npn_protocols_len);
     /* Accept both OPENSSL_NPN_NEGOTIATED and OPENSSL_NPN_NO_OVERLAP. */
-    OPENSSL_assert(ret == OPENSSL_NPN_NEGOTIATED
-                   || ret == OPENSSL_NPN_NO_OVERLAP);
+    TEST_check(ret == OPENSSL_NPN_NEGOTIATED || ret == OPENSSL_NPN_NO_OVERLAP);
     return SSL_TLSEXT_ERR_OK;
 }
 
@@ -328,7 +329,7 @@ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
         parse_protos(extra->server2.npn_protocols,
                      &server2_ctx_data->npn_protocols,
                      &server2_ctx_data->npn_protocols_len);
-        OPENSSL_assert(server2_ctx != NULL);
+        TEST_check(server2_ctx != NULL);
         SSL_CTX_set_next_protos_advertised_cb(server2_ctx, server_npn_cb,
                                               server2_ctx_data);
     }
@@ -347,7 +348,7 @@ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
         SSL_CTX_set_alpn_select_cb(server_ctx, server_alpn_cb, server_ctx_data);
     }
     if (extra->server2.alpn_protocols != NULL) {
-        OPENSSL_assert(server2_ctx != NULL);
+        TEST_check(server2_ctx != NULL);
         parse_protos(extra->server2.alpn_protocols,
                      &server2_ctx_data->alpn_protocols,
                      &server2_ctx_data->alpn_protocols_len);
@@ -359,8 +360,8 @@ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
         parse_protos(extra->client.alpn_protocols,
                      &alpn_protos, &alpn_protos_len);
         /* Reversed return value convention... */
-        OPENSSL_assert(SSL_CTX_set_alpn_protos(client_ctx, alpn_protos,
-                                               alpn_protos_len) == 0);
+        TEST_check(SSL_CTX_set_alpn_protos(client_ctx, alpn_protos,
+                                           alpn_protos_len) == 0);
         OPENSSL_free(alpn_protos);
     }
 
@@ -370,10 +371,24 @@ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
      */
     ticket_key_len = SSL_CTX_set_tlsext_ticket_keys(server_ctx, NULL, 0);
     ticket_keys = OPENSSL_zalloc(ticket_key_len);
-    OPENSSL_assert(ticket_keys != NULL);
-    OPENSSL_assert(SSL_CTX_set_tlsext_ticket_keys(server_ctx, ticket_keys,
-                                                  ticket_key_len) == 1);
+    TEST_check(ticket_keys != NULL);
+    TEST_check(SSL_CTX_set_tlsext_ticket_keys(server_ctx, ticket_keys,
+                                              ticket_key_len) == 1);
     OPENSSL_free(ticket_keys);
+
+#ifndef OPENSSL_NO_CT
+    TEST_check(SSL_CTX_set_default_ctlog_list_file(client_ctx));
+    switch (extra->client.ct_validation) {
+    case SSL_TEST_CT_VALIDATION_PERMISSIVE:
+        TEST_check(SSL_CTX_enable_ct(client_ctx, SSL_CT_VALIDATION_PERMISSIVE));
+        break;
+    case SSL_TEST_CT_VALIDATION_STRICT:
+        TEST_check(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. */
@@ -509,9 +524,9 @@ static char *dup_str(const unsigned char *in, size_t len)
         return NULL;
 
     /* Assert that the string does not contain NUL-bytes. */
-    OPENSSL_assert(OPENSSL_strnlen((const char*)(in), len) == len);
+    TEST_check(OPENSSL_strnlen((const char*)(in), len) == len);
     ret = OPENSSL_strndup((const char*)(in), len);
-    OPENSSL_assert(ret != NULL);
+    TEST_check(ret != NULL);
     return ret;
 }
 
@@ -544,13 +559,14 @@ static HANDSHAKE_RESULT *do_handshake_internal(
 
     server = SSL_new(server_ctx);
     client = SSL_new(client_ctx);
-    OPENSSL_assert(server != NULL && client != NULL);
+    TEST_check(server != NULL);
+    TEST_check(client != NULL);
 
     configure_handshake_ssl(server, client, extra);
     if (session_in != NULL) {
         /* In case we're testing resumption without tickets. */
-        OPENSSL_assert(SSL_CTX_add_session(server_ctx, session_in));
-        OPENSSL_assert(SSL_set_session(client, session_in));
+        TEST_check(SSL_CTX_add_session(server_ctx, session_in));
+        TEST_check(SSL_set_session(client, session_in));
     }
 
     memset(&server_ex_data, 0, sizeof(server_ex_data));
@@ -561,7 +577,7 @@ static HANDSHAKE_RESULT *do_handshake_internal(
     client_to_server = BIO_new(BIO_s_mem());
     server_to_client = BIO_new(BIO_s_mem());
 
-    OPENSSL_assert(client_to_server != NULL && server_to_client != NULL);
+    TEST_check(client_to_server != NULL && server_to_client != NULL);
 
     /* Non-blocking bio. */
     BIO_set_nbio(client_to_server, 1);
@@ -572,16 +588,16 @@ static HANDSHAKE_RESULT *do_handshake_internal(
 
     /* The bios are now owned by the SSL object. */
     SSL_set_bio(client, server_to_client, client_to_server);
-    OPENSSL_assert(BIO_up_ref(server_to_client) > 0);
-    OPENSSL_assert(BIO_up_ref(client_to_server) > 0);
+    TEST_check(BIO_up_ref(server_to_client) > 0);
+    TEST_check(BIO_up_ref(client_to_server) > 0);
     SSL_set_bio(server, client_to_server, server_to_client);
 
     ex_data_idx = SSL_get_ex_new_index(0, "ex data", NULL, NULL, NULL);
-    OPENSSL_assert(ex_data_idx >= 0);
+    TEST_check(ex_data_idx >= 0);
 
-    OPENSSL_assert(SSL_set_ex_data(server, ex_data_idx,
+    TEST_check(SSL_set_ex_data(server, ex_data_idx,
                                    &server_ex_data) == 1);
-    OPENSSL_assert(SSL_set_ex_data(client, ex_data_idx,
+    TEST_check(SSL_set_ex_data(client, ex_data_idx,
                                    &client_ex_data) == 1);
 
     SSL_set_info_callback(server, &info_cb);
@@ -690,7 +706,7 @@ HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
     if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_SIMPLE)
         goto end;
 
-    OPENSSL_assert(test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME);
+    TEST_check(test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME);
 
     if (result->result != SSL_TEST_SUCCESS) {
         result->result = SSL_TEST_FIRST_HANDSHAKE_FAILED;
diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t
index 877a087..1530bc2 100644
--- a/test/recipes/80-test_ssl_new.t
+++ b/test/recipes/80-test_ssl_new.t
@@ -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";
@@ -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.
@@ -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,
@@ -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) {
diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t
index 631adbf..22bb226 100644
--- a/test/recipes/80-test_ssl_old.t
+++ b/test/recipes/80-test_ssl_old.t
@@ -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 {
@@ -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;
diff --git a/test/ssl-tests/12-ct.conf b/test/ssl-tests/12-ct.conf
new file mode 100644
index 0000000..22fa18d
--- /dev/null
+++ b/test/ssl-tests/12-ct.conf
@@ -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
+
+
diff --git a/test/ssl-tests/12-ct.conf.in b/test/ssl-tests/12-ct.conf.in
new file mode 100644
index 0000000..9964d01
--- /dev/null
+++ b/test/ssl-tests/12-ct.conf.in
@@ -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",
+	},
+    },
+);
diff --git a/test/ssl_test.c b/test/ssl_test.c
index fcf48bc..c2324bf 100644
--- a/test/ssl_test.c
+++ b/test/ssl_test.c
@@ -230,14 +230,14 @@ static int execute_test(SSL_TEST_FIXTURE fixture)
         if (test_ctx->extra.server.servername_callback !=
             SSL_TEST_SERVERNAME_CB_NONE) {
             server2_ctx = SSL_CTX_new(DTLS_server_method());
-            OPENSSL_assert(server2_ctx != NULL);
+            TEST_check(server2_ctx != NULL);
         }
         client_ctx = SSL_CTX_new(DTLS_client_method());
         if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) {
             resume_server_ctx = SSL_CTX_new(DTLS_server_method());
             resume_client_ctx = SSL_CTX_new(DTLS_client_method());
-            OPENSSL_assert(resume_server_ctx != NULL);
-            OPENSSL_assert(resume_client_ctx != NULL);
+            TEST_check(resume_server_ctx != NULL);
+            TEST_check(resume_client_ctx != NULL);
         }
     }
 #endif
@@ -247,22 +247,22 @@ static int execute_test(SSL_TEST_FIXTURE fixture)
         if (test_ctx->extra.server.servername_callback !=
             SSL_TEST_SERVERNAME_CB_NONE) {
             server2_ctx = SSL_CTX_new(TLS_server_method());
-            OPENSSL_assert(server2_ctx != NULL);
+            TEST_check(server2_ctx != NULL);
         }
         client_ctx = SSL_CTX_new(TLS_client_method());
 
         if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) {
             resume_server_ctx = SSL_CTX_new(TLS_server_method());
             resume_client_ctx = SSL_CTX_new(TLS_client_method());
-            OPENSSL_assert(resume_server_ctx != NULL);
-            OPENSSL_assert(resume_client_ctx != NULL);
+            TEST_check(resume_server_ctx != NULL);
+            TEST_check(resume_client_ctx != NULL);
         }
     }
 
-    OPENSSL_assert(server_ctx != NULL);
-    OPENSSL_assert(client_ctx != NULL);
+    TEST_check(server_ctx != NULL);
+    TEST_check(client_ctx != NULL);
 
-    OPENSSL_assert(CONF_modules_load(conf, fixture.test_app, 0) > 0);
+    TEST_check(CONF_modules_load(conf, fixture.test_app, 0) > 0);
 
     if (!SSL_CTX_config(server_ctx, "server")
         || !SSL_CTX_config(client_ctx, "client")) {
@@ -323,12 +323,12 @@ int main(int argc, char **argv)
         return 1;
 
     conf = NCONF_new(NULL);
-    OPENSSL_assert(conf != NULL);
+    TEST_check(conf != NULL);
 
     /* argv[1] should point to the test conf file */
-    OPENSSL_assert(NCONF_load(conf, argv[1], NULL) > 0);
+    TEST_check(NCONF_load(conf, argv[1], NULL) > 0);
 
-    OPENSSL_assert(NCONF_get_number_e(conf, NULL, "num_tests", &num_tests));
+    TEST_check(NCONF_get_number_e(conf, NULL, "num_tests", &num_tests));
 
     ADD_ALL_TESTS(test_handshake, (int)(num_tests));
     result = run_tests(argv[0]);
diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c
index d4a7c8b..3913e9f 100644
--- a/test/ssl_test_ctx.c
+++ b/test/ssl_test_ctx.c
@@ -14,6 +14,7 @@
 
 #include "e_os.h"
 #include "ssl_test_ctx.h"
+#include "testutil.h"
 
 /* True enums and other test configuration values that map to an int. */
 typedef struct {
@@ -142,7 +143,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),
@@ -286,7 +287,7 @@ const char *ssl_test_method_name(ssl_test_method_t method)
     {                                                                   \
         OPENSSL_free(ctx->field);                                       \
         ctx->field = OPENSSL_strdup(value);                             \
-        OPENSSL_assert(ctx->field != NULL);                             \
+        TEST_check(ctx->field != NULL);                                 \
         return 1;                                                       \
     }
 
@@ -328,6 +329,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) {
@@ -385,6 +414,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. */
@@ -401,14 +431,14 @@ static const ssl_test_server_option ssl_test_server_options[] = {
 };
 
 /*
- * Since these methods are used to create tests, we use OPENSSL_assert liberally
+ * Since these methods are used to create tests, we use TEST_check liberally
  * for malloc failures and other internal errors.
  */
 SSL_TEST_CTX *SSL_TEST_CTX_new()
 {
     SSL_TEST_CTX *ret;
     ret = OPENSSL_zalloc(sizeof(*ret));
-    OPENSSL_assert(ret != NULL);
+    TEST_check(ret != NULL);
     return ret;
 }
 
@@ -444,7 +474,7 @@ static int parse_client_options(SSL_TEST_CLIENT_CONF *client, const CONF *conf,
     size_t j;
 
     sk_conf = NCONF_get_section(conf, client_section);
-    OPENSSL_assert(sk_conf != NULL);
+    TEST_check(sk_conf != NULL);
 
     for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
         int found = 0;
@@ -477,7 +507,7 @@ static int parse_server_options(SSL_TEST_SERVER_CONF *server, const CONF *conf,
     size_t j;
 
     sk_conf = NCONF_get_section(conf, server_section);
-    OPENSSL_assert(sk_conf != NULL);
+    TEST_check(sk_conf != NULL);
 
     for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
         int found = 0;
@@ -510,10 +540,10 @@ SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
     size_t j;
 
     sk_conf = NCONF_get_section(conf, test_section);
-    OPENSSL_assert(sk_conf != NULL);
+    TEST_check(sk_conf != NULL);
 
     ctx = SSL_TEST_CTX_new();
-    OPENSSL_assert(ctx != NULL);
+    TEST_check(ctx != NULL);
 
     for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
         int found = 0;
diff --git a/test/ssl_test_ctx.h b/test/ssl_test_ctx.h
index a939f3d..916b31a 100644
--- a/test/ssl_test_ctx.h
+++ b/test/ssl_test_ctx.h
@@ -60,6 +60,11 @@ typedef enum {
     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.
@@ -72,6 +77,7 @@ typedef struct {
     /* 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 {
@@ -150,6 +156,7 @@ const char *ssl_servername_callback_name(ssl_servername_callback_t
 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|.
diff --git a/test/ssl_test_ctx_test.c b/test/ssl_test_ctx_test.c
index a779ed1..60bd573 100644
--- a/test/ssl_test_ctx_test.c
+++ b/test/ssl_test_ctx_test.c
@@ -54,6 +54,12 @@ static int SSL_TEST_CLIENT_CONF_equal(SSL_TEST_CLIENT_CONF *client,
     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;
 }
 
@@ -168,7 +174,7 @@ static SSL_TEST_CTX_TEST_FIXTURE set_up(const char *const test_case_name)
     SSL_TEST_CTX_TEST_FIXTURE fixture;
     fixture.test_case_name = test_case_name;
     fixture.expected_ctx = SSL_TEST_CTX_new();
-    OPENSSL_assert(fixture.expected_ctx != NULL);
+    TEST_check(fixture.expected_ctx != NULL);
     return fixture;
 }
 
@@ -248,7 +254,7 @@ static int test_good_configuration()
     fixture.expected_ctx->extra.client.servername = SSL_TEST_SERVERNAME_SERVER2;
     fixture.expected_ctx->extra.client.npn_protocols =
         OPENSSL_strdup("foo,bar");
-    OPENSSL_assert(fixture.expected_ctx->extra.client.npn_protocols != NULL);
+    TEST_check(fixture.expected_ctx->extra.client.npn_protocols != NULL);
 
     fixture.expected_ctx->extra.server.servername_callback =
         SSL_TEST_SERVERNAME_IGNORE_MISMATCH;
@@ -256,14 +262,18 @@ static int test_good_configuration()
 
     fixture.expected_ctx->resume_extra.server2.alpn_protocols =
         OPENSSL_strdup("baz");
-    OPENSSL_assert(
+    TEST_check(
         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();
 }
 
 static const char *bad_configurations[] = {
     "ssltest_unknown_option",
+    "ssltest_wrong_section",
     "ssltest_unknown_expected_result",
     "ssltest_unknown_alert",
     "ssltest_unknown_protocol",
@@ -274,6 +284,7 @@ static const char *bad_configurations[] = {
     "ssltest_unknown_method",
     "ssltest_unknown_handshake_mode",
     "ssltest_unknown_resumption_expected",
+    "ssltest_unknown_ct_validation",
 };
 
 static int test_bad_configuration(int idx)
@@ -291,11 +302,10 @@ int main(int argc, char **argv)
         return 1;
 
     conf = NCONF_new(NULL);
-    OPENSSL_assert(conf != NULL);
+    TEST_check(conf != NULL);
 
     /* argv[1] should point to test/ssl_test_ctx_test.conf */
-    OPENSSL_assert(NCONF_load(conf, argv[1], NULL) > 0);
-
+    TEST_check(NCONF_load(conf, argv[1], NULL) > 0);
 
     ADD_TEST(test_empty_configuration);
     ADD_TEST(test_good_configuration);
diff --git a/test/ssl_test_ctx_test.conf b/test/ssl_test_ctx_test.conf
index 73878a1..3c46d96 100644
--- a/test/ssl_test_ctx_test.conf
+++ b/test/ssl_test_ctx_test.conf
@@ -4,6 +4,7 @@
 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
@@ -20,6 +21,9 @@ VerifyCallback = RejectAll
 ServerName = server2
 NPNProtocols = foo,bar
 
+[ssltest_good_resume_client_extra]
+CTValidation = Strict
+
 [ssltest_good_server_extra]
 ServerNameCallback = IgnoreMismatch
 BrokenSessionTicket = Yes
@@ -30,22 +34,37 @@ ALPNProtocols = baz
 [ssltest_unknown_option]
 UnknownOption = Foo
 
+[ssltest_wrong_section]
+server = ssltest_wrong_section_server
+
+[ssltest_wrong_section_server]
+VerifyCallback = RejectAll
+
 [ssltest_unknown_expected_result]
 ExpectedResult = Foo
 
 [ssltest_unknown_alert]
-ServerAlert = Foo
+ExpectedServerAlert = Foo
 
 [ssltest_unknown_protocol]
 Protocol = Foo
 
 [ssltest_unknown_verify_callback]
-ClientVerifyCallback = Foo
+client = ssltest_unknown_verify_callback_client
+
+[ssltest_unknown_verify_callback_client]
+VerifyCallback = Foo
 
 [ssltest_unknown_servername]
+client = ssltest_unknown_servername_client
+
+[ssltest_unknown_servername_client]
 ServerName = Foo
 
 [ssltest_unknown_servername_callback]
+server = ssltest_unknown_servername_server
+
+[ssltest_unknown_servername_server]
 ServerNameCallback = Foo
 
 [ssltest_unknown_session_ticket_expected]
@@ -59,3 +78,9 @@ HandshakeMode = Foo
 
 [ssltest_unknown_resumption_expected]
 ResumptionExpected = Foo
+
+[ssltest_unknown_ct_validation]
+client = ssltest_unknown_ct_validation_client
+
+[ssltest_unknown_ct_validation_client]
+CTCallback = Foo
diff --git a/test/testutil.h b/test/testutil.h
index 0ff2a82..14b7b09 100644
--- a/test/testutil.h
+++ b/test/testutil.h
@@ -10,6 +10,8 @@
 #ifndef HEADER_TESTUTIL_H
 # define HEADER_TESTUTIL_H
 
+#include <openssl/err.h>
+
 /*-
  * SETUP_TEST_FIXTURE and EXECUTE_TEST macros for test case functions.
  *
@@ -94,3 +96,16 @@ int run_tests(const char *test_prog_name);
  */
 int strings_equal(const char *desc, const char *s1, const char *s2);
 #endif                          /* HEADER_TESTUTIL_H */
+
+/*
+ * For "impossible" conditions such as malloc failures or bugs in test code,
+ * where continuing the test would be meaningless. Note that OPENSSL_assert
+ * is fatal, and is never compiled out.
+ */
+#define TEST_check(condition)                   \
+    do {                                        \
+        if (!(condition)) {                     \
+            ERR_print_errors_fp(stderr);        \
+            OPENSSL_assert(!#condition);        \
+        }                                       \
+    } while (0);


More information about the openssl-commits mailing list