diff options
author | Matt Caswell <matt@openssl.org> | 2017-06-02 13:10:50 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2017-06-16 10:57:59 +0100 |
commit | ca0413ae14f8fc9cc840b8acaadd150ea290285f (patch) | |
tree | 5c2289d687d2bb9d0b008d509cfba05309f7f9a2 /test/sslapitest.c | |
parent | a055a8815587f402d700093dea0dec6bf34631a3 (diff) |
Add a test for a server changing the ciphersuite
Test that if a server selects a differenct ciphersuite with the same hash
in TLSv1.3 then this is accepted by the client.
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/3623)
Diffstat (limited to 'test/sslapitest.c')
-rw-r--r-- | test/sslapitest.c | 127 |
1 files changed, 125 insertions, 2 deletions
diff --git a/test/sslapitest.c b/test/sslapitest.c index ecbb8b7162..6162625d06 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -18,6 +18,7 @@ #include "ssltestlib.h" #include "testutil.h" #include "e_os.h" +#include "../ssl/ssl_locl.h" static char *cert = NULL; static char *privkey = NULL; @@ -1797,8 +1798,129 @@ static int test_early_data_tls1_2(int idx) return testresult; } -# endif -#endif +# endif /* OPENSSL_NO_TLS1_2 */ + +static int test_ciphersuite_change(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + SSL_SESSION *clntsess = NULL; + int testresult = 0; + const SSL_CIPHER *aes_128_gcm_sha256 = NULL; + + /* Create a session based on SHA-256 */ + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), + TLS_client_method(), &sctx, + &cctx, cert, privkey)) + || !TEST_true(SSL_CTX_set_cipher_list(cctx, + "TLS13-AES-128-GCM-SHA256")) + || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, + &clientssl, NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + clntsess = SSL_get1_session(clientssl); + /* Save for later */ + aes_128_gcm_sha256 = SSL_SESSION_get0_cipher(clntsess); + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + SSL_free(serverssl); + SSL_free(clientssl); + serverssl = clientssl = NULL; + + /* Check we can resume a session with a different SHA-256 ciphersuite */ + if (!TEST_true(SSL_CTX_set_cipher_list(cctx, + "TLS13-CHACHA20-POLY1305-SHA256")) + || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(SSL_set_session(clientssl, clntsess)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE)) + || !TEST_true(SSL_session_reused(clientssl))) + goto end; + + SSL_SESSION_free(clntsess); + clntsess = SSL_get1_session(clientssl); + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + SSL_free(serverssl); + SSL_free(clientssl); + serverssl = clientssl = NULL; + + /* + * Check attempting to resume a SHA-256 session with no SHA-256 ciphersuites + * fails. + */ + if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "TLS13-AES-256-GCM-SHA384")) + || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(SSL_set_session(clientssl, clntsess)) + || !TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_SSL)) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), + SSL_R_NO_SHARED_CIPHER)) + goto end; + + SSL_SESSION_free(clntsess); + clntsess = NULL; + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + SSL_free(serverssl); + SSL_free(clientssl); + serverssl = clientssl = NULL; + + /* Create a session based on SHA384 */ + if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "TLS13-AES-256-GCM-SHA384")) + || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, + &clientssl, NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + clntsess = SSL_get1_session(clientssl); + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + SSL_free(serverssl); + SSL_free(clientssl); + serverssl = clientssl = NULL; + + if (!TEST_true(SSL_CTX_set_cipher_list(cctx, + "TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384")) + || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(SSL_set_session(clientssl, clntsess)) + || !TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_WANT_READ))) + goto end; + + /* Trick the client into thinking this session is for a different digest */ + clntsess->cipher = aes_128_gcm_sha256; + clntsess->cipher_id = clntsess->cipher->id; + + /* + * Server has selected a SHA-384 ciphersuite, but client thinks the session + * is for SHA-256, so it should bail out. + */ + if (!TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_SSL)) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), + SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED)) + goto end; + + testresult = 1; + + end: + SSL_SESSION_free(clntsess); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + +#endif /* OPENSSL_NO_TLS1_3 */ static int clntaddoldcb = 0; static int clntparseoldcb = 0; @@ -2222,6 +2344,7 @@ int test_main(int argc, char *argv[]) # endif #endif #ifndef OPENSSL_NO_TLS1_3 + ADD_TEST(test_ciphersuite_change); ADD_ALL_TESTS(test_custom_exts, 5); #else ADD_ALL_TESTS(test_custom_exts, 3); |