Newer
Older
if (!TEST_ptr(tmp = SSL_SESSION_dup(sess2))
|| !TEST_true(SSL_CTX_remove_session(sctx, sess2)))
goto end;
SSL_SESSION_free(sess2);
}
new_called = remove_called = get_called = 0;
get_sess_val = sess2;
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl2,
&clientssl2, NULL, NULL))
|| !TEST_true(SSL_set_session(clientssl2, sess1))
|| !TEST_true(create_ssl_connection(serverssl2, clientssl2,
SSL_ERROR_NONE))
|| !TEST_true(SSL_session_reused(clientssl2)))
goto end;
if (use_ext_cache) {
if (!TEST_int_eq(new_called, 0)
|| !TEST_int_eq(remove_called, 0))
goto end;
if (maxprot == TLS1_3_VERSION) {
if (!TEST_int_eq(get_called, 0))
goto end;
} else {
if (!TEST_int_eq(get_called, 1))
goto end;
}
}
end:
SSL_free(serverssl1);
SSL_free(clientssl1);
SSL_free(serverssl2);
SSL_free(clientssl2);
SSL_SESSION_free(sess1);
SSL_SESSION_free(sess2);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return testresult;
}
#endif /* !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) */
static int test_session_with_only_int_cache(void)
{
#ifndef OPENSSL_NO_TLS1_3
if (!execute_test_session(TLS1_3_VERSION, 1, 0))
return 0;
#endif
#ifndef OPENSSL_NO_TLS1_2
return execute_test_session(TLS1_2_VERSION, 1, 0);
#else
return 1;
#endif
static int test_session_with_only_ext_cache(void)
{
#ifndef OPENSSL_NO_TLS1_3
if (!execute_test_session(TLS1_3_VERSION, 0, 1))
return 0;
#endif
#ifndef OPENSSL_NO_TLS1_2
return execute_test_session(TLS1_2_VERSION, 0, 1);
#else
return 1;
#endif
static int test_session_with_both_cache(void)
{
#ifndef OPENSSL_NO_TLS1_3
if (!execute_test_session(TLS1_3_VERSION, 1, 1))
return 0;
#endif
#ifndef OPENSSL_NO_TLS1_2
return execute_test_session(TLS1_2_VERSION, 1, 1);
#else
return 1;
#endif
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
#define USE_NULL 0
#define USE_BIO_1 1
#define USE_BIO_2 2
#define TOTAL_SSL_SET_BIO_TESTS (3 * 3 * 3 * 3)
static void setupbio(BIO **res, BIO *bio1, BIO *bio2, int type)
{
switch (type) {
case USE_NULL:
*res = NULL;
break;
case USE_BIO_1:
*res = bio1;
break;
case USE_BIO_2:
*res = bio2;
break;
}
}
static int test_ssl_set_bio(int idx)
{
BIO *irbio = NULL, *iwbio = NULL, *nrbio = NULL, *nwbio = NULL;
SSL *ssl = NULL;
int initrbio, initwbio, newrbio, newwbio;
int testresult = 0;
initrbio = idx % 3;
idx /= 3;
initwbio = idx % 3;
idx /= 3;
newrbio = idx % 3;
idx /= 3;
newwbio = idx;
if (!TEST_int_le(newwbio, 2))
return 0;
if (!TEST_ptr(ctx = SSL_CTX_new(TLS_method()))
|| !TEST_ptr(ssl = SSL_new(ctx)))
goto end;
if (initrbio == USE_BIO_1
|| initwbio == USE_BIO_1
|| newrbio == USE_BIO_1
if (!TEST_ptr(bio1 = BIO_new(BIO_s_mem())))
if (initrbio == USE_BIO_2
|| initwbio == USE_BIO_2
|| newrbio == USE_BIO_2
if (!TEST_ptr(bio2 = BIO_new(BIO_s_mem())))
goto end;
}
setupbio(&irbio, bio1, bio2, initrbio);
setupbio(&iwbio, bio1, bio2, initwbio);
/*
* We want to maintain our own refs to these BIO, so do an up ref for each
* BIO that will have ownership transferred in the SSL_set_bio() call
*/
if (irbio != NULL)
BIO_up_ref(irbio);
if (iwbio != NULL && iwbio != irbio)
BIO_up_ref(iwbio);
SSL_set_bio(ssl, irbio, iwbio);
setupbio(&nrbio, bio1, bio2, newrbio);
setupbio(&nwbio, bio1, bio2, newwbio);
/*
* We will (maybe) transfer ownership again so do more up refs.
* SSL_set_bio() has some really complicated ownership rules where BIOs have
* already been set!
*/
if (nrbio != NULL
&& nrbio != irbio
&& (nwbio != iwbio || nrbio != nwbio))
if (nwbio != NULL
&& nwbio != nrbio
&& (nwbio != iwbio || (nwbio == iwbio && irbio == iwbio)))
BIO_up_ref(nwbio);
SSL_set_bio(ssl, nrbio, nwbio);
testresult = 1;
end:
SSL_free(ssl);
BIO_free(bio1);
BIO_free(bio2);
/*
* This test is checking that the ref counting for SSL_set_bio is correct.
* If we get here and we did too many frees then we will fail in the above
* functions. If we haven't done enough then this will only be detected in
* a crypto-mdebug build
*/
SSL_CTX_free(ctx);
return testresult;
}
typedef enum { NO_BIO_CHANGE, CHANGE_RBIO, CHANGE_WBIO } bio_change_t;
static int execute_test_ssl_bio(int pop_ssl, bio_change_t change_bio)
{
BIO *sslbio = NULL, *membio1 = NULL, *membio2 = NULL;
if (!TEST_ptr(ctx = SSL_CTX_new(TLS_method()))
|| !TEST_ptr(ssl = SSL_new(ctx))
|| !TEST_ptr(sslbio = BIO_new(BIO_f_ssl()))
|| !TEST_ptr(membio1 = BIO_new(BIO_s_mem())))
goto end;
BIO_set_ssl(sslbio, ssl, BIO_CLOSE);
/*
* If anything goes wrong here then we could leak memory, so this will
* be caught in a crypto-mdebug build
*/
BIO_push(sslbio, membio1);
/* Verify changing the rbio/wbio directly does not cause leaks */
if (!TEST_ptr(membio2 = BIO_new(BIO_s_mem())))
SSL_set0_rbio(ssl, membio2);
SSL_set0_wbio(ssl, membio2);
BIO_pop(sslbio);
else
BIO_pop(membio1);
testresult = 1;
end:
BIO_free(membio1);
BIO_free(sslbio);
SSL_free(ssl);
SSL_CTX_free(ctx);
return testresult;
}
static int test_ssl_bio_pop_next_bio(void)
{
return execute_test_ssl_bio(0, NO_BIO_CHANGE);
}
static int test_ssl_bio_pop_ssl_bio(void)
{
return execute_test_ssl_bio(1, NO_BIO_CHANGE);
}
static int test_ssl_bio_change_rbio(void)
{
return execute_test_ssl_bio(0, CHANGE_RBIO);
}
static int test_ssl_bio_change_wbio(void)
{
return execute_test_ssl_bio(0, CHANGE_WBIO);
typedef struct {
/* The list of sig algs */
const int *list;
/* The length of the list */
size_t listlen;
/* A sigalgs list in string format */
const char *liststr;
/* Whether setting the list should succeed */
int valid;
/* Whether creating a connection with the list should succeed */
int connsuccess;
} sigalgs_list;
static const int validlist1[] = {NID_sha256, EVP_PKEY_RSA};
static const int validlist2[] = {NID_sha256, EVP_PKEY_RSA, NID_sha512, EVP_PKEY_EC};
static const int validlist3[] = {NID_sha512, EVP_PKEY_EC};
static const int invalidlist1[] = {NID_undef, EVP_PKEY_RSA};
static const int invalidlist2[] = {NID_sha256, NID_undef};
static const int invalidlist3[] = {NID_sha256, EVP_PKEY_RSA, NID_sha256};
static const int invalidlist4[] = {NID_sha256};
static const sigalgs_list testsigalgs[] = {
{validlist1, OSSL_NELEM(validlist1), NULL, 1, 1},
{validlist2, OSSL_NELEM(validlist2), NULL, 1, 1},
{validlist3, OSSL_NELEM(validlist3), NULL, 1, 0},
{NULL, 0, "RSA+SHA256:ECDSA+SHA512", 1, 1},
{NULL, 0, "ECDSA+SHA512", 1, 0},
{invalidlist1, OSSL_NELEM(invalidlist1), NULL, 0, 0},
{invalidlist2, OSSL_NELEM(invalidlist2), NULL, 0, 0},
{invalidlist3, OSSL_NELEM(invalidlist3), NULL, 0, 0},
{invalidlist4, OSSL_NELEM(invalidlist4), NULL, 0, 0},
{NULL, 0, "RSA", 0, 0},
{NULL, 0, "SHA256", 0, 0},
{NULL, 0, "RSA+SHA256:SHA256", 0, 0},
static int test_set_sigalgs(int idx)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
int testresult = 0;
const sigalgs_list *curr;
int testctx;
/* Should never happen */
if (!TEST_size_t_le((size_t)idx, OSSL_NELEM(testsigalgs) * 2))
return 0;
testctx = ((size_t)idx < OSSL_NELEM(testsigalgs));
curr = testctx ? &testsigalgs[idx]
: &testsigalgs[idx - OSSL_NELEM(testsigalgs)];
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
TLS_client_method(), &sctx,
&cctx, cert, privkey)))
/*
* TODO(TLS1.3): These APIs cannot set TLSv1.3 sig algs so we just test it
* for TLSv1.2 for now until we add a new API.
*/
SSL_CTX_set_max_proto_version(cctx, TLS1_2_VERSION);
if (curr->list != NULL)
ret = SSL_CTX_set1_sigalgs(cctx, curr->list, curr->listlen);
else
ret = SSL_CTX_set1_sigalgs_list(cctx, curr->liststr);
if (!ret) {
if (curr->valid)
TEST_info("Failure setting sigalgs in SSL_CTX (%d)\n", idx);
else
testresult = 1;
goto end;
}
if (!curr->valid) {
TEST_info("Not-failed setting sigalgs in SSL_CTX (%d)\n", idx);
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
&clientssl, NULL, NULL)))
goto end;
if (!testctx) {
int ret;
if (curr->list != NULL)
ret = SSL_set1_sigalgs(clientssl, curr->list, curr->listlen);
else
ret = SSL_set1_sigalgs_list(clientssl, curr->liststr);
if (!ret) {
if (curr->valid)
TEST_info("Failure setting sigalgs in SSL (%d)\n", idx);
else
testresult = 1;
goto end;
}
if (!TEST_int_eq(create_ssl_connection(serverssl, clientssl,
SSL_ERROR_NONE),
curr->connsuccess))
goto end;
testresult = 1;
end:
SSL_free(serverssl);
SSL_free(clientssl);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return testresult;
}
static SSL_SESSION *clientpsk = NULL;
static SSL_SESSION *serverpsk = NULL;
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
static const char *pskid = "Identity";
static const char *srvid;
static int use_session_cb_cnt = 0;
static int find_session_cb_cnt = 0;
static int use_session_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id,
size_t *idlen, SSL_SESSION **sess)
{
switch (++use_session_cb_cnt) {
case 1:
/* The first call should always have a NULL md */
if (md != NULL)
return 0;
break;
case 2:
/* The second call should always have an md */
if (md == NULL)
return 0;
break;
default:
/* We should only be called a maximum of twice */
return 0;
}
if (clientpsk != NULL)
SSL_SESSION_up_ref(clientpsk);
*sess = clientpsk;
*id = (const unsigned char *)pskid;
*idlen = strlen(pskid);
return 1;
}
static int find_session_cb(SSL *ssl, const unsigned char *identity,
size_t identity_len, SSL_SESSION **sess)
{
find_session_cb_cnt++;
/* We should only ever be called a maximum of twice per connection */
if (find_session_cb_cnt > 2)
return 0;
if (serverpsk == NULL)
return 0;
/* Identity should match that set by the client */
if (strlen(srvid) != identity_len
|| strncmp(srvid, (const char *)identity, identity_len) != 0) {
/* No PSK found, continue but without a PSK */
*sess = NULL;
return 1;
}
SSL_SESSION_up_ref(serverpsk);
*sess = serverpsk;
#define MSG1 "Hello"
#define MSG2 "World."
#define MSG3 "This"
#define MSG4 "is"
#define MSG5 "a"
#define MSG6 "test"
#define MSG7 "message."
#define TLS13_AES_256_GCM_SHA384_BYTES ((const unsigned char *)"\x13\x02")
/*
* Helper method to setup objects for early data test. Caller frees objects on
* error.
*/
static int setupearly_data_test(SSL_CTX **cctx, SSL_CTX **sctx, SSL **clientssl,
SSL **serverssl, SSL_SESSION **sess, int idx)
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
TLS_client_method(), sctx,
cctx, cert, privkey)))
if (idx == 1) {
/* When idx == 1 we repeat the tests with read_ahead set */
SSL_CTX_set_read_ahead(*cctx, 1);
SSL_CTX_set_read_ahead(*sctx, 1);
} else if (idx == 2) {
/* When idx == 2 we are doing early_data with a PSK. Set up callbacks */
SSL_CTX_set_psk_use_session_callback(*cctx, use_session_cb);
SSL_CTX_set_psk_find_session_callback(*sctx, find_session_cb);
use_session_cb_cnt = 0;
find_session_cb_cnt = 0;
srvid = pskid;
if (!TEST_true(create_ssl_objects(*sctx, *cctx, serverssl, clientssl,
/*
* For one of the run throughs (doesn't matter which one), we'll try sending
* some SNI data in the initial ClientHello. This will be ignored (because
* there is no SNI cb set up by the server), so it should not impact
* early_data.
*/
if (idx == 1
&& !TEST_true(SSL_set_tlsext_host_name(*clientssl, "localhost")))
return 0;
if (idx == 2) {
/* Create the PSK */
const SSL_CIPHER *cipher = NULL;
const unsigned char key[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
0x2c, 0x2d, 0x2e, 0x2f
};
cipher = SSL_CIPHER_find(*clientssl, TLS13_AES_256_GCM_SHA384_BYTES);
clientpsk = SSL_SESSION_new();
if (!TEST_ptr(clientpsk)
|| !TEST_true(SSL_SESSION_set1_master_key(clientpsk, key,
|| !TEST_true(SSL_SESSION_set_cipher(clientpsk, cipher))
SSL_SESSION_set_protocol_version(clientpsk,
TLS1_3_VERSION))
/*
* We just choose an arbitrary value for max_early_data which
* should be big enough for testing purposes.
*/
|| !TEST_true(SSL_SESSION_set_max_early_data(clientpsk,
0x100))
|| !TEST_true(SSL_SESSION_up_ref(clientpsk))) {
SSL_SESSION_free(clientpsk);
clientpsk = NULL;
serverpsk = clientpsk;
*sess = clientpsk;
return 1;
}
if (sess == NULL)
return 1;
if (!TEST_true(create_ssl_connection(*serverssl, *clientssl,
SSL_ERROR_NONE)))
return 0;
*sess = SSL_get1_session(*clientssl);
SSL_shutdown(*clientssl);
SSL_shutdown(*serverssl);
SSL_free(*serverssl);
SSL_free(*clientssl);
*serverssl = *clientssl = NULL;
if (!TEST_true(create_ssl_objects(*sctx, *cctx, serverssl,
clientssl, NULL, NULL))
|| !TEST_true(SSL_set_session(*clientssl, *sess)))
static int test_early_data_read_write(int idx)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
int testresult = 0;
SSL_SESSION *sess = NULL;
unsigned char buf[20], data[1024];
size_t readbytes, written, eoedlen, rawread, rawwritten;
BIO *rbio;
if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl,
&serverssl, &sess, idx)))
goto end;
/* Write and read some early data */
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written))
|| !TEST_size_t_eq(written, strlen(MSG1))
|| !TEST_int_eq(SSL_read_early_data(serverssl, buf,
sizeof(buf), &readbytes),
SSL_READ_EARLY_DATA_SUCCESS)
|| !TEST_mem_eq(MSG1, readbytes, buf, strlen(MSG1))
|| !TEST_int_eq(SSL_get_early_data_status(serverssl),
SSL_EARLY_DATA_ACCEPTED))
* Server should be able to write data, and client should be able to
if (!TEST_true(SSL_write_early_data(serverssl, MSG2, strlen(MSG2),
&written))
|| !TEST_size_t_eq(written, strlen(MSG2))
|| !TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes))
|| !TEST_mem_eq(buf, readbytes, MSG2, strlen(MSG2)))
goto end;
/* Even after reading normal data, client should be able write early data */
if (!TEST_true(SSL_write_early_data(clientssl, MSG3, strlen(MSG3),
&written))
|| !TEST_size_t_eq(written, strlen(MSG3)))
/* Server should still be able read early data after writing data */
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_SUCCESS)
|| !TEST_mem_eq(buf, readbytes, MSG3, strlen(MSG3)))
/* Write more data from server and read it from client */
if (!TEST_true(SSL_write_early_data(serverssl, MSG4, strlen(MSG4),
&written))
|| !TEST_size_t_eq(written, strlen(MSG4))
|| !TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes))
|| !TEST_mem_eq(buf, readbytes, MSG4, strlen(MSG4)))
goto end;
/*
* If client writes normal data it should mean writing early data is no
* longer possible.
*/
if (!TEST_true(SSL_write_ex(clientssl, MSG5, strlen(MSG5), &written))
|| !TEST_size_t_eq(written, strlen(MSG5))
|| !TEST_int_eq(SSL_get_early_data_status(clientssl),
SSL_EARLY_DATA_ACCEPTED))
/*
* At this point the client has written EndOfEarlyData, ClientFinished and
* normal (fully protected) data. We are going to cause a delay between the
* arrival of EndOfEarlyData and ClientFinished. We read out all the data
* in the read BIO, and then just put back the EndOfEarlyData message.
*/
rbio = SSL_get_rbio(serverssl);
if (!TEST_true(BIO_read_ex(rbio, data, sizeof(data), &rawread))
|| !TEST_size_t_lt(rawread, sizeof(data))
|| !TEST_size_t_gt(rawread, SSL3_RT_HEADER_LENGTH))
/* Record length is in the 4th and 5th bytes of the record header */
eoedlen = SSL3_RT_HEADER_LENGTH + (data[3] << 8 | data[4]);
if (!TEST_true(BIO_write_ex(rbio, data, eoedlen, &rawwritten))
|| !TEST_size_t_eq(rawwritten, eoedlen))
/* Server should be told that there is no more early data */
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_FINISH)
|| !TEST_size_t_eq(readbytes, 0))
/*
* Server has not finished init yet, so should still be able to write early
* data.
*/
if (!TEST_true(SSL_write_early_data(serverssl, MSG6, strlen(MSG6),
&written))
|| !TEST_size_t_eq(written, strlen(MSG6)))
/* Push the ClientFinished and the normal data back into the server rbio */
if (!TEST_true(BIO_write_ex(rbio, data + eoedlen, rawread - eoedlen,
&rawwritten))
|| !TEST_size_t_eq(rawwritten, rawread - eoedlen))
if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
|| !TEST_size_t_eq(readbytes, strlen(MSG5)))
/* Client and server should not be able to write/read early data now */
if (!TEST_false(SSL_write_early_data(clientssl, MSG6, strlen(MSG6),
&written)))
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_ERROR))
/* Client should be able to read the data sent by the server */
if (!TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes))
|| !TEST_mem_eq(buf, readbytes, MSG6, strlen(MSG6)))
/*
* Make sure we process the NewSessionTicket. This arrives post-handshake.
* We attempt a read which we do not expect to return any data.
*/
if (!TEST_false(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes)))
/* Server should be able to write normal data */
if (!TEST_true(SSL_write_ex(serverssl, MSG7, strlen(MSG7), &written))
|| !TEST_size_t_eq(written, strlen(MSG7))
|| !TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes))
|| !TEST_mem_eq(buf, readbytes, MSG7, strlen(MSG7)))
/* We keep the PSK session around if using PSK */
if (idx != 2)
SSL_SESSION_free(sess);
use_session_cb_cnt = 0;
find_session_cb_cnt = 0;
SSL_shutdown(clientssl);
SSL_shutdown(serverssl);
SSL_free(serverssl);
SSL_free(clientssl);
serverssl = clientssl = NULL;
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
&clientssl, NULL, NULL))
|| !TEST_true(SSL_set_session(clientssl, sess)))
goto end;
/* Write and read some early data */
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written))
|| !TEST_size_t_eq(written, strlen(MSG1))
|| !TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_SUCCESS)
|| !TEST_mem_eq(buf, readbytes, MSG1, strlen(MSG1)))
if (!TEST_int_gt(SSL_connect(clientssl), 0)
|| !TEST_int_gt(SSL_accept(serverssl), 0))
/* Client and server should not be able to write/read early data now */
if (!TEST_false(SSL_write_early_data(clientssl, MSG6, strlen(MSG6),
&written)))
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_ERROR))
goto end;
ERR_clear_error();
/* Client and server should be able to write/read normal data */
if (!TEST_true(SSL_write_ex(clientssl, MSG5, strlen(MSG5), &written))
|| !TEST_size_t_eq(written, strlen(MSG5))
|| !TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
|| !TEST_size_t_eq(readbytes, strlen(MSG5)))
if (sess != clientpsk)
SSL_SESSION_free(sess);
SSL_SESSION_free(clientpsk);
SSL_SESSION_free(serverpsk);
clientpsk = serverpsk = NULL;
SSL_free(serverssl);
SSL_free(clientssl);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return testresult;
}
* Helper function to test that a server attempting to read early data can
* handle a connection from a client where the early data should be skipped.
static int early_data_skip_helper(int hrr, int idx)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
int testresult = 0;
unsigned char buf[20];
size_t readbytes, written;
if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl,
&serverssl, &sess, idx)))
if (hrr) {
/* Force an HRR to occur */
if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256")))
goto end;
} else if (idx == 2) {
/*
* We force early_data rejection by ensuring the PSK identity is
* unrecognised
*/
srvid = "Dummy Identity";
} else {
/*
* Deliberately corrupt the creation time. We take 20 seconds off the
* time. It could be any value as long as it is not within tolerance.
* This should mean the ticket is rejected.
*/
if (!TEST_true(SSL_SESSION_set_time(sess, time(NULL) - 20)))
goto end;
}
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written))
|| !TEST_size_t_eq(written, strlen(MSG1)))
goto end;
/* Server should reject the early data and skip over it */
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_FINISH)
|| !TEST_size_t_eq(readbytes, 0)
|| !TEST_int_eq(SSL_get_early_data_status(serverssl),
SSL_EARLY_DATA_REJECTED))
if (hrr) {
/*
* Finish off the handshake. We perform the same writes and reads as
* further down but we expect them to fail due to the incomplete
* handshake.
*/
if (!TEST_false(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written))
|| !TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf),
&readbytes)))
goto end;
}
/* Should be able to send normal data despite rejection of early data */
if (!TEST_true(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written))
|| !TEST_size_t_eq(written, strlen(MSG2))
|| !TEST_int_eq(SSL_get_early_data_status(clientssl),
SSL_EARLY_DATA_REJECTED)
|| !TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
|| !TEST_mem_eq(buf, readbytes, MSG2, strlen(MSG2)))
if (sess != clientpsk)
SSL_SESSION_free(clientpsk);
SSL_SESSION_free(serverpsk);
clientpsk = serverpsk = NULL;
SSL_SESSION_free(sess);
SSL_free(serverssl);
SSL_free(clientssl);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return testresult;
}
/*
* Test that a server attempting to read early data can handle a connection
* from a client where the early data is not acceptable.
*/
static int test_early_data_skip(int idx)
{
return early_data_skip_helper(0, idx);
}
/*
* Test that a server attempting to read early data can handle a connection
* from a client where an HRR occurs.
*/
static int test_early_data_skip_hrr(int idx)
{
return early_data_skip_helper(1, idx);
}
/*
* Test that a server attempting to read early data can handle a connection
* from a client that doesn't send any.
*/
static int test_early_data_not_sent(int idx)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
int testresult = 0;
unsigned char buf[20];
size_t readbytes, written;
if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl,
&serverssl, &sess, idx)))
goto end;
/* Write some data - should block due to handshake with server */
SSL_set_connect_state(clientssl);
if (!TEST_false(SSL_write_ex(clientssl, MSG1, strlen(MSG1), &written)))
goto end;
/* Server should detect that early data has not been sent */
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_FINISH)
|| !TEST_size_t_eq(readbytes, 0)
|| !TEST_int_eq(SSL_get_early_data_status(serverssl),
SSL_EARLY_DATA_NOT_SENT)
|| !TEST_int_eq(SSL_get_early_data_status(clientssl),
SSL_EARLY_DATA_NOT_SENT))
goto end;
/* Continue writing the message we started earlier */
if (!TEST_true(SSL_write_ex(clientssl, MSG1, strlen(MSG1), &written))
|| !TEST_size_t_eq(written, strlen(MSG1))
|| !TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
|| !TEST_mem_eq(buf, readbytes, MSG1, strlen(MSG1))
|| !SSL_write_ex(serverssl, MSG2, strlen(MSG2), &written)
|| !TEST_size_t_eq(written, strlen(MSG2)))
/*
* Should block due to the NewSessionTicket arrival unless we're using
* read_ahead
*/
if (!TEST_false(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes)))
if (!TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes))
|| !TEST_mem_eq(buf, readbytes, MSG2, strlen(MSG2)))
/* If using PSK then clientpsk and sess are the same */
SSL_SESSION_free(serverpsk);
clientpsk = serverpsk = NULL;
SSL_free(serverssl);
SSL_free(clientssl);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return testresult;
}
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
static const char *servhostname;
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, servhostname) == 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, unsigned char *outlen,
const unsigned char *in, unsigned int inlen, void *arg)
{
unsigned int i, protlen = 0;
const unsigned char *prot;
for (i = 0, prot = in; i < inlen; i += protlen, prot += protlen) {
protlen = *(prot++);
if (inlen - i < protlen)
return SSL_TLSEXT_ERR_NOACK;
if (protlen == strlen(servalpn)
&& memcmp(prot, "goodalpn", protlen) == 0) {
*out = prot;
*outlen = protlen;
return SSL_TLSEXT_ERR_OK;
}
}
return SSL_TLSEXT_ERR_NOACK;
}
/* Test that a PSK can be used to send early_data */