Newer
Older
if (!TEST_int_eq(new_called, 1)
|| !TEST_int_eq(remove_called, 0)
|| !TEST_int_eq(get_called, 0))
goto end;
/*
* Delete the session from the internal cache to force a lookup from
* the external cache. We take a copy first because
* SSL_CTX_remove_session() also marks the session as non-resumable.
*/
if (use_int_cache) {
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 (!TEST_int_eq(remove_called, 0))
goto end;
if (maxprot == TLS1_3_VERSION) {
/*
* Every time we issue a NewSessionTicket we are creating a new
* session for next time in TLSv1.3
*/
if (!TEST_int_eq(new_called, 1)
|| !TEST_int_eq(get_called, 0))
if (!TEST_int_eq(new_called, 0)
|| !TEST_int_eq(get_called, 1))
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
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
#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);
#if !defined(OPENSSL_NO_TLS1_2) || defined(OPENSSL_NO_TLS1_3)
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)];
Richard Levitte
committed
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
TLS1_VERSION, TLS_MAX_VERSION,
&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;
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 psk_client_cb_cnt = 0;
static int psk_server_cb_cnt = 0;
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
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;
}
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *id,
unsigned int max_id_len,
unsigned char *psk,
unsigned int max_psk_len)
{
unsigned int psklen = 0;
psk_client_cb_cnt++;
if (strlen(pskid) + 1 > max_id_len)
return 0;
/* We should only ever be called a maximum of twice per connection */
if (psk_client_cb_cnt > 2)
return 0;
if (clientpsk == NULL)
return 0;
/* We'll reuse the PSK we set up for TLSv1.3 */
if (SSL_SESSION_get_master_key(clientpsk, NULL, 0) > max_psk_len)
return 0;
psklen = SSL_SESSION_get_master_key(clientpsk, psk, max_psk_len);
strncpy(id, pskid, max_id_len);
return psklen;
}
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;
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
static unsigned int psk_server_cb(SSL *ssl, const char *identity,
unsigned char *psk, unsigned int max_psk_len)
{
unsigned int psklen = 0;
psk_server_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 (strcmp(srvid, identity) != 0) {
return 0;
}
/* We'll reuse the PSK we set up for TLSv1.3 */
if (SSL_SESSION_get_master_key(serverpsk, NULL, 0) > max_psk_len)
return 0;
psklen = SSL_SESSION_get_master_key(serverpsk, psk, max_psk_len);
return psklen;
}
#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")
#define TLS13_AES_128_GCM_SHA256_BYTES ((const unsigned char *)"\x13\x01")
/*
* 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)
Richard Levitte
committed
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
TLS1_VERSION, TLS_MAX_VERSION,
sctx, cctx, cert, privkey))
|| !TEST_true(SSL_CTX_set_max_early_data(*sctx,
SSL3_RT_MAX_PLAIN_LENGTH))
|| !TEST_true(SSL_CTX_set_max_early_data(*cctx,
SSL3_RT_MAX_PLAIN_LENGTH)))
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;
}
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
static int test_early_data_replay(int idx)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
int testresult = 0;
SSL_SESSION *sess = NULL;
if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl,
&serverssl, &sess, idx)))
goto end;
/*
* The server is configured to accept early data. Create a connection to
* "use up" the ticket
*/
if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))
|| !TEST_true(SSL_session_reused(clientssl)))
goto end;
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))
|| !TEST_true(create_ssl_connection(serverssl, clientssl,
SSL_ERROR_NONE))
/*
* This time we should not have resumed the session because we
* already used it once.
*/
|| !TEST_false(SSL_session_reused(clientssl)))
goto end;
testresult = 1;
end:
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, (long)(time(NULL) - 20))))
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)))