Latest update.
This commit is contained in:
+234
-23
@@ -7,6 +7,14 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* We need access to the deprecated low level HMAC APIs for legacy purposes
|
||||
* when the deprecated calls are not hidden
|
||||
*/
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
# define OPENSSL_SUPPRESS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -19,6 +27,7 @@
|
||||
#include <openssl/txt_db.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
#include "ssltestlib.h"
|
||||
#include "testutil.h"
|
||||
@@ -101,6 +110,17 @@ static unsigned char serverinfov2[] = {
|
||||
0xff /* Dummy extension data */
|
||||
};
|
||||
|
||||
static int hostname_cb(SSL *s, int *al, void *arg)
|
||||
{
|
||||
const char *hostname = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
|
||||
|
||||
if (hostname != NULL && (strcmp(hostname, "goodhost") == 0
|
||||
|| strcmp(hostname, "altgoodhost") == 0))
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
|
||||
static void client_keylog_callback(const SSL *ssl, const char *line)
|
||||
{
|
||||
int line_length = strlen(line);
|
||||
@@ -3187,16 +3207,6 @@ static int test_early_data_not_sent(int idx)
|
||||
return testresult;
|
||||
}
|
||||
|
||||
static int hostname_cb(SSL *s, int *al, void *arg)
|
||||
{
|
||||
const char *hostname = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
|
||||
|
||||
if (hostname != NULL && strcmp(hostname, "goodhost") == 0)
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
|
||||
static const char *servalpn;
|
||||
|
||||
static int alpn_select_cb(SSL *ssl, const unsigned char **out,
|
||||
@@ -3289,16 +3299,16 @@ static int test_early_data_psk(int idx)
|
||||
|
||||
case 3:
|
||||
/*
|
||||
* Set inconsistent SNI (server detected). In this case the connection
|
||||
* will succeed but reject early_data.
|
||||
* Set inconsistent SNI (server side). In this case the connection
|
||||
* will succeed and accept early_data. In TLSv1.3 on the server side SNI
|
||||
* is associated with each handshake - not the session. Therefore it
|
||||
* should not matter that we used a different server name last time.
|
||||
*/
|
||||
SSL_SESSION_free(serverpsk);
|
||||
serverpsk = SSL_SESSION_dup(clientpsk);
|
||||
if (!TEST_ptr(serverpsk)
|
||||
|| !TEST_true(SSL_SESSION_set1_hostname(serverpsk, "badhost")))
|
||||
goto end;
|
||||
edstatus = SSL_EARLY_DATA_REJECTED;
|
||||
readearlyres = SSL_READ_EARLY_DATA_FINISH;
|
||||
/* Fall through */
|
||||
case 4:
|
||||
/* Set consistent SNI */
|
||||
@@ -6077,6 +6087,7 @@ static SSL_TICKET_RETURN dec_tick_cb(SSL *s, SSL_SESSION *ss,
|
||||
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
static int tick_key_cb(SSL *s, unsigned char key_name[16],
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH], EVP_CIPHER_CTX *ctx,
|
||||
HMAC_CTX *hctx, int enc)
|
||||
@@ -6094,6 +6105,32 @@ static int tick_key_cb(SSL *s, unsigned char key_name[16],
|
||||
|
||||
return tick_key_renew ? 2 : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int tick_key_evp_cb(SSL *s, unsigned char key_name[16],
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH],
|
||||
EVP_CIPHER_CTX *ctx, EVP_MAC_CTX *hctx, int enc)
|
||||
{
|
||||
const unsigned char tick_aes_key[16] = "0123456789abcdef";
|
||||
unsigned char tick_hmac_key[16] = "0123456789abcdef";
|
||||
OSSL_PARAM params[3];
|
||||
|
||||
tick_key_cb_called = 1;
|
||||
memset(iv, 0, AES_BLOCK_SIZE);
|
||||
memset(key_name, 0, 16);
|
||||
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
|
||||
"SHA256", 0);
|
||||
params[1] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
||||
tick_hmac_key,
|
||||
sizeof(tick_hmac_key));
|
||||
params[2] = OSSL_PARAM_construct_end();
|
||||
if (!EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, tick_aes_key, iv, enc)
|
||||
|| !EVP_MAC_CTX_set_params(hctx, params)
|
||||
|| !EVP_MAC_init(hctx))
|
||||
return -1;
|
||||
|
||||
return tick_key_renew ? 2 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the various ticket callbacks
|
||||
@@ -6105,10 +6142,14 @@ static int tick_key_cb(SSL *s, unsigned char key_name[16],
|
||||
* Test 5: TLSv1.3, no ticket key callback, ticket, no renewal
|
||||
* Test 6: TLSv1.2, no ticket key callback, ticket, renewal
|
||||
* Test 7: TLSv1.3, no ticket key callback, ticket, renewal
|
||||
* Test 8: TLSv1.2, ticket key callback, ticket, no renewal
|
||||
* Test 9: TLSv1.3, ticket key callback, ticket, no renewal
|
||||
* Test 10: TLSv1.2, ticket key callback, ticket, renewal
|
||||
* Test 11: TLSv1.3, ticket key callback, ticket, renewal
|
||||
* Test 8: TLSv1.2, old ticket key callback, ticket, no renewal
|
||||
* Test 9: TLSv1.3, old ticket key callback, ticket, no renewal
|
||||
* Test 10: TLSv1.2, old ticket key callback, ticket, renewal
|
||||
* Test 11: TLSv1.3, old ticket key callback, ticket, renewal
|
||||
* Test 12: TLSv1.2, ticket key callback, ticket, no renewal
|
||||
* Test 13: TLSv1.3, ticket key callback, ticket, no renewal
|
||||
* Test 14: TLSv1.2, ticket key callback, ticket, renewal
|
||||
* Test 15: TLSv1.3, ticket key callback, ticket, renewal
|
||||
*/
|
||||
static int test_ticket_callbacks(int tst)
|
||||
{
|
||||
@@ -6125,11 +6166,15 @@ static int test_ticket_callbacks(int tst)
|
||||
if (tst % 2 == 1)
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_DEPRECATED_3_0
|
||||
if (tst >= 8 && tst <= 11)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
gen_tick_called = dec_tick_called = tick_key_cb_called = 0;
|
||||
|
||||
/* Which tests the ticket key callback should request renewal for */
|
||||
if (tst == 10 || tst == 11)
|
||||
if (tst == 10 || tst == 11 || tst == 14 || tst == 15)
|
||||
tick_key_renew = 1;
|
||||
else
|
||||
tick_key_renew = 0;
|
||||
@@ -6179,9 +6224,15 @@ static int test_ticket_callbacks(int tst)
|
||||
NULL)))
|
||||
goto end;
|
||||
|
||||
if (tst >= 8
|
||||
&& !TEST_true(SSL_CTX_set_tlsext_ticket_key_cb(sctx, tick_key_cb)))
|
||||
goto end;
|
||||
if (tst >= 12) {
|
||||
if (!TEST_true(SSL_CTX_set_tlsext_ticket_key_evp_cb(sctx, tick_key_evp_cb)))
|
||||
goto end;
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
} else if (tst >= 8) {
|
||||
if (!TEST_true(SSL_CTX_set_tlsext_ticket_key_cb(sctx, tick_key_cb)))
|
||||
goto end;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
|
||||
NULL, NULL))
|
||||
@@ -6918,10 +6969,169 @@ end:
|
||||
}
|
||||
#endif /* OPENSSL_NO_TLS1_2 */
|
||||
|
||||
/*
|
||||
* Test 0: Client sets servername and server acknowledges it (TLSv1.2)
|
||||
* Test 1: Client sets servername and server does not acknowledge it (TLSv1.2)
|
||||
* Test 2: Client sets inconsistent servername on resumption (TLSv1.2)
|
||||
* Test 3: Client does not set servername on initial handshake (TLSv1.2)
|
||||
* Test 4: Client does not set servername on resumption handshake (TLSv1.2)
|
||||
* Test 5: Client sets servername and server acknowledges it (TLSv1.3)
|
||||
* Test 6: Client sets servername and server does not acknowledge it (TLSv1.3)
|
||||
* Test 7: Client sets inconsistent servername on resumption (TLSv1.3)
|
||||
* Test 8: Client does not set servername on initial handshake(TLSv1.3)
|
||||
* Test 9: Client does not set servername on resumption handshake (TLSv1.3)
|
||||
*/
|
||||
static int test_servername(int tst)
|
||||
{
|
||||
SSL_CTX *cctx = NULL, *sctx = NULL;
|
||||
SSL *clientssl = NULL, *serverssl = NULL;
|
||||
int testresult = 0;
|
||||
SSL_SESSION *sess = NULL;
|
||||
const char *sexpectedhost = NULL, *cexpectedhost = NULL;
|
||||
|
||||
#ifdef OPENSSL_NO_TLS1_2
|
||||
if (tst <= 4)
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_TLS1_3
|
||||
if (tst >= 5)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
|
||||
TLS_client_method(),
|
||||
TLS1_VERSION,
|
||||
(tst <= 4) ? TLS1_2_VERSION
|
||||
: TLS1_3_VERSION,
|
||||
&sctx, &cctx, cert, privkey))
|
||||
|| !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
|
||||
NULL, NULL)))
|
||||
goto end;
|
||||
|
||||
if (tst != 1 && tst != 6) {
|
||||
if (!TEST_true(SSL_CTX_set_tlsext_servername_callback(sctx,
|
||||
hostname_cb)))
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (tst != 3 && tst != 8) {
|
||||
if (!TEST_true(SSL_set_tlsext_host_name(clientssl, "goodhost")))
|
||||
goto end;
|
||||
sexpectedhost = cexpectedhost = "goodhost";
|
||||
}
|
||||
|
||||
if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
|
||||
goto end;
|
||||
|
||||
if (!TEST_str_eq(SSL_get_servername(clientssl, TLSEXT_NAMETYPE_host_name),
|
||||
cexpectedhost)
|
||||
|| !TEST_str_eq(SSL_get_servername(serverssl,
|
||||
TLSEXT_NAMETYPE_host_name),
|
||||
sexpectedhost))
|
||||
goto end;
|
||||
|
||||
/* Now repeat with a resumption handshake */
|
||||
|
||||
if (!TEST_int_eq(SSL_shutdown(clientssl), 0)
|
||||
|| !TEST_ptr_ne(sess = SSL_get1_session(clientssl), NULL)
|
||||
|| !TEST_true(SSL_SESSION_is_resumable(sess))
|
||||
|| !TEST_int_eq(SSL_shutdown(serverssl), 0))
|
||||
goto end;
|
||||
|
||||
SSL_free(clientssl);
|
||||
SSL_free(serverssl);
|
||||
clientssl = serverssl = NULL;
|
||||
|
||||
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL,
|
||||
NULL)))
|
||||
goto end;
|
||||
|
||||
if (!TEST_true(SSL_set_session(clientssl, sess)))
|
||||
goto end;
|
||||
|
||||
sexpectedhost = cexpectedhost = "goodhost";
|
||||
if (tst == 2 || tst == 7) {
|
||||
/* Set an inconsistent hostname */
|
||||
if (!TEST_true(SSL_set_tlsext_host_name(clientssl, "altgoodhost")))
|
||||
goto end;
|
||||
/*
|
||||
* In TLSv1.2 we expect the hostname from the original handshake, in
|
||||
* TLSv1.3 we expect the hostname from this handshake
|
||||
*/
|
||||
if (tst == 7)
|
||||
sexpectedhost = cexpectedhost = "altgoodhost";
|
||||
|
||||
if (!TEST_str_eq(SSL_get_servername(clientssl,
|
||||
TLSEXT_NAMETYPE_host_name),
|
||||
"altgoodhost"))
|
||||
goto end;
|
||||
} else if (tst == 4 || tst == 9) {
|
||||
/*
|
||||
* A TLSv1.3 session does not associate a session with a servername,
|
||||
* but a TLSv1.2 session does.
|
||||
*/
|
||||
if (tst == 9)
|
||||
sexpectedhost = cexpectedhost = NULL;
|
||||
|
||||
if (!TEST_str_eq(SSL_get_servername(clientssl,
|
||||
TLSEXT_NAMETYPE_host_name),
|
||||
cexpectedhost))
|
||||
goto end;
|
||||
} else {
|
||||
if (!TEST_true(SSL_set_tlsext_host_name(clientssl, "goodhost")))
|
||||
goto end;
|
||||
/*
|
||||
* In a TLSv1.2 resumption where the hostname was not acknowledged
|
||||
* we expect the hostname on the server to be empty. On the client we
|
||||
* return what was requested in this case.
|
||||
*
|
||||
* Similarly if the client didn't set a hostname on an original TLSv1.2
|
||||
* session but is now, the server hostname will be empty, but the client
|
||||
* is as we set it.
|
||||
*/
|
||||
if (tst == 1 || tst == 3)
|
||||
sexpectedhost = NULL;
|
||||
|
||||
if (!TEST_str_eq(SSL_get_servername(clientssl,
|
||||
TLSEXT_NAMETYPE_host_name),
|
||||
"goodhost"))
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
|
||||
goto end;
|
||||
|
||||
if (!TEST_true(SSL_session_reused(clientssl))
|
||||
|| !TEST_true(SSL_session_reused(serverssl))
|
||||
|| !TEST_str_eq(SSL_get_servername(clientssl,
|
||||
TLSEXT_NAMETYPE_host_name),
|
||||
cexpectedhost)
|
||||
|| !TEST_str_eq(SSL_get_servername(serverssl,
|
||||
TLSEXT_NAMETYPE_host_name),
|
||||
sexpectedhost))
|
||||
goto end;
|
||||
|
||||
testresult = 1;
|
||||
|
||||
end:
|
||||
SSL_SESSION_free(sess);
|
||||
SSL_free(serverssl);
|
||||
SSL_free(clientssl);
|
||||
SSL_CTX_free(sctx);
|
||||
SSL_CTX_free(cctx);
|
||||
|
||||
return testresult;
|
||||
}
|
||||
|
||||
OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile\n")
|
||||
|
||||
int setup_tests(void)
|
||||
{
|
||||
if (!test_skip_common_options()) {
|
||||
TEST_error("Error parsing test options\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!TEST_ptr(certsdir = test_get_argument(0))
|
||||
|| !TEST_ptr(srpvfile = test_get_argument(1))
|
||||
|| !TEST_ptr(tmpfilename = test_get_argument(2)))
|
||||
@@ -7060,7 +7270,7 @@ int setup_tests(void)
|
||||
ADD_ALL_TESTS(test_info_callback, 6);
|
||||
ADD_ALL_TESTS(test_ssl_pending, 2);
|
||||
ADD_ALL_TESTS(test_ssl_get_shared_ciphers, OSSL_NELEM(shared_ciphers_data));
|
||||
ADD_ALL_TESTS(test_ticket_callbacks, 12);
|
||||
ADD_ALL_TESTS(test_ticket_callbacks, 16);
|
||||
ADD_ALL_TESTS(test_shutdown, 7);
|
||||
ADD_ALL_TESTS(test_cert_cb, 6);
|
||||
ADD_ALL_TESTS(test_client_cert_cb, 2);
|
||||
@@ -7068,6 +7278,7 @@ int setup_tests(void)
|
||||
#ifndef OPENSSL_NO_TLS1_2
|
||||
ADD_ALL_TESTS(test_multiblock_write, OSSL_NELEM(multiblock_cipherlist_data));
|
||||
#endif
|
||||
ADD_ALL_TESTS(test_servername, 10);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user