forked from wolfSSL/wolfssl
tests: add tests for stateless dtls v1.2 cookie
This commit is contained in:
271
tests/api.c
271
tests/api.c
@@ -58699,6 +58699,263 @@ static int test_wolfSSL_DTLS_fragment_buckets(void)
|
||||
}
|
||||
|
||||
#endif
|
||||
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
|
||||
static int test_wolfSSL_dtls_stateless2(void)
|
||||
{
|
||||
WOLFSSL *ssl_c, *ssl_c2, *ssl_s;
|
||||
struct test_memio_ctx test_ctx;
|
||||
WOLFSSL_CTX *ctx_c, *ctx_s;
|
||||
int ret;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
ssl_c2 = wolfSSL_new(ctx_c);
|
||||
if (ssl_c2 == NULL)
|
||||
return -2;
|
||||
wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
|
||||
wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
|
||||
/* send CH */
|
||||
ret = wolfSSL_connect(ssl_c2);
|
||||
if (ret == 0 || ssl_c2->error != WANT_READ)
|
||||
return -3;
|
||||
ret = wolfSSL_accept(ssl_s);
|
||||
if (ret == 0 || ssl_s->error != WANT_READ)
|
||||
return -4;
|
||||
if (test_ctx.c_len == 0)
|
||||
return -5;
|
||||
/* consume HRR */
|
||||
test_ctx.c_len = 0;
|
||||
ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
|
||||
if (ret != 0)
|
||||
return -6;
|
||||
wolfSSL_free(ssl_c2);
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MAX_FRAGMENT
|
||||
static int test_wolfSSL_dtls_stateless_maxfrag(void)
|
||||
{
|
||||
WOLFSSL *ssl_c, *ssl_c2, *ssl_s;
|
||||
struct test_memio_ctx test_ctx;
|
||||
WOLFSSL_CTX *ctx_c, *ctx_s;
|
||||
word16 max_fragment;
|
||||
int ret;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
ssl_c2 = wolfSSL_new(ctx_c);
|
||||
if (ssl_c2 == NULL)
|
||||
return -2;
|
||||
ret = wolfSSL_UseMaxFragment(ssl_c2, WOLFSSL_MFL_2_8);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return -3;
|
||||
wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
|
||||
wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
|
||||
max_fragment = ssl_s->max_fragment;
|
||||
/* send CH */
|
||||
ret = wolfSSL_connect(ssl_c2);
|
||||
if (ret == 0 || ssl_c2->error != WANT_READ)
|
||||
return -4;
|
||||
ret = wolfSSL_accept(ssl_s);
|
||||
if (ret == 0 || ssl_s->error != WANT_READ)
|
||||
return -5;
|
||||
/* CH without cookie shouldn't change state */
|
||||
if (ssl_s->max_fragment != max_fragment)
|
||||
return -6;
|
||||
if (test_ctx.c_len == 0)
|
||||
return -7;
|
||||
/* consume HRR from buffer */
|
||||
test_ctx.c_len = 0;
|
||||
ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
|
||||
if (ret != 0)
|
||||
return -8;
|
||||
wolfSSL_free(ssl_c2);
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
#endif /* HAVE_MAX_FRAGMENT */
|
||||
|
||||
#if defined(WOLFSSL_DTLS_NO_HVR_ON_RESUME)
|
||||
#define ROUNDS_WITH_HVR 4
|
||||
#define ROUNDS_WITHOUT_HVR 2
|
||||
#define HANDSHAKE_TYPE_OFFSET DTLS_RECORD_HEADER_SZ
|
||||
static int buf_is_hvr(const byte *data, int len)
|
||||
{
|
||||
if (len < DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ)
|
||||
return 0;
|
||||
return data[HANDSHAKE_TYPE_OFFSET] == hello_verify_request;
|
||||
}
|
||||
|
||||
static int _test_wolfSSL_dtls_stateless_resume(byte useticket, byte bad)
|
||||
{
|
||||
struct test_memio_ctx test_ctx;
|
||||
WOLFSSL_CTX *ctx_c, *ctx_s;
|
||||
WOLFSSL *ssl_c, *ssl_s;
|
||||
WOLFSSL_SESSION *sess;
|
||||
int ret, round_trips;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
if (useticket) {
|
||||
ret = wolfSSL_UseSessionTicket(ssl_c);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
round_trips = ROUNDS_WITH_HVR;
|
||||
ret = test_memio_do_handshake(ssl_c, ssl_s, round_trips, &round_trips);
|
||||
if (ret != 0)
|
||||
return -3;
|
||||
if (round_trips != ROUNDS_WITH_HVR)
|
||||
return -4;
|
||||
sess = wolfSSL_get1_session(ssl_c);
|
||||
if (sess == NULL)
|
||||
return -5;
|
||||
wolfSSL_shutdown(ssl_c);
|
||||
wolfSSL_shutdown(ssl_s);
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
test_ctx.c_len = test_ctx.s_len = 0;
|
||||
/* make resumption invalid */
|
||||
if (bad) {
|
||||
if (useticket) {
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
sess->ticket[0] = !sess->ticket[0];
|
||||
#endif /* HAVE_SESSION_TICKET */
|
||||
}
|
||||
else {
|
||||
sess->sessionID[0] = !sess->sessionID[0];
|
||||
}
|
||||
}
|
||||
ssl_c = wolfSSL_new(ctx_c);
|
||||
ssl_s = wolfSSL_new(ctx_s);
|
||||
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
|
||||
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
|
||||
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
|
||||
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
|
||||
ret = wolfSSL_set_session(ssl_c, sess);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return -6;
|
||||
ret = wolfSSL_connect(ssl_c);
|
||||
if (ret == WOLFSSL_SUCCESS || ssl_c->error != WANT_READ)
|
||||
return -7;
|
||||
ret = wolfSSL_accept(ssl_s);
|
||||
if (ret == WOLFSSL_SUCCESS || ssl_s->error != WANT_READ)
|
||||
return -8;
|
||||
if (bad && !buf_is_hvr(test_ctx.c_buff, test_ctx.c_len))
|
||||
return -9;
|
||||
if (!bad && buf_is_hvr(test_ctx.c_buff, test_ctx.c_len))
|
||||
return -10;
|
||||
if (!useticket) {
|
||||
ret = test_memio_do_handshake(ssl_c, ssl_s, 10, &round_trips);
|
||||
if (ret != 0)
|
||||
return -11;
|
||||
if (bad && round_trips != ROUNDS_WITH_HVR - 1)
|
||||
return -12;
|
||||
if (!bad && round_trips != ROUNDS_WITHOUT_HVR - 1)
|
||||
return -13;
|
||||
}
|
||||
wolfSSL_SESSION_free(sess);
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
|
||||
static int test_wolfSSL_dtls_stateless_resume(void)
|
||||
{
|
||||
int ret;
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
ret = _test_wolfSSL_dtls_stateless_resume(1, 0);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = _test_wolfSSL_dtls_stateless_resume(1, 1);
|
||||
if (ret != 0)
|
||||
return ret - 100;
|
||||
#endif /* HAVE_SESION_TICKET */
|
||||
ret = _test_wolfSSL_dtls_stateless_resume(0, 0);
|
||||
if (ret != 0)
|
||||
return ret - 200;
|
||||
ret = _test_wolfSSL_dtls_stateless_resume(0, 1);
|
||||
if (ret != 0)
|
||||
return ret - 300;
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
|
||||
|
||||
#if !defined(NO_OLD_TLS)
|
||||
static int test_wolfSSL_dtls_stateless_downgrade(void)
|
||||
{
|
||||
WOLFSSL_CTX *ctx_c, *ctx_c2, *ctx_s;
|
||||
WOLFSSL *ssl_c, *ssl_c2, *ssl_s;
|
||||
struct test_memio_ctx test_ctx;
|
||||
int ret;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
ret = wolfSSL_CTX_SetMinVersion(ctx_s, WOLFSSL_DTLSV1);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return -2;
|
||||
ctx_c2 = wolfSSL_CTX_new(wolfDTLSv1_client_method());
|
||||
if (ctx_c2 == NULL)
|
||||
return -3;
|
||||
wolfSSL_SetIORecv(ctx_c2, test_memio_read_cb);
|
||||
wolfSSL_SetIOSend(ctx_c2, test_memio_write_cb);
|
||||
ssl_c2 = wolfSSL_new(ctx_c2);
|
||||
if (ssl_c2 == NULL)
|
||||
return -4;
|
||||
wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
|
||||
wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
|
||||
/* send CH */
|
||||
ret = wolfSSL_connect(ssl_c2);
|
||||
if (ret == 0 || ssl_c2->error != WANT_READ)
|
||||
return -5;
|
||||
ret = wolfSSL_accept(ssl_s);
|
||||
if (ret == 0 || ssl_s->error != WANT_READ)
|
||||
return -6;
|
||||
if (test_ctx.c_len == 0)
|
||||
return -7;
|
||||
/* consume HRR */
|
||||
test_ctx.c_len = 0;
|
||||
ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
|
||||
if (ret != 0)
|
||||
return -8;
|
||||
wolfSSL_free(ssl_c2);
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_c2);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
#endif /* !defined(NO_OLD_TLS) */
|
||||
|
||||
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)*/
|
||||
|
||||
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
@@ -59882,6 +60139,20 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_wolfSSL_DtlsUpdateWindow),
|
||||
TEST_DECL(test_wolfSSL_DTLS_fragment_buckets),
|
||||
#endif
|
||||
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
||||
TEST_DECL(test_wolfSSL_dtls_stateless_resume),
|
||||
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
|
||||
#ifdef HAVE_MAX_FRAGMENT
|
||||
TEST_DECL(test_wolfSSL_dtls_stateless_maxfrag),
|
||||
#endif /* HAVE_MAX_FRAGMENT */
|
||||
TEST_DECL(test_wolfSSL_dtls_stateless2),
|
||||
#if !defined(NO_OLD_TLS)
|
||||
TEST_DECL(test_wolfSSL_dtls_stateless_downgrade),
|
||||
#endif /* !defined(NO_OLD_TLS) */
|
||||
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
* !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) */
|
||||
TEST_DECL(test_WOLFSSL_dtls_version_alert),
|
||||
TEST_DECL(test_ForceZero),
|
||||
|
||||
|
@@ -5136,8 +5136,7 @@ void DEBUG_WRITE_DER(const byte* der, int derSz, const char* fileName);
|
||||
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))\
|
||||
|| \
|
||||
(defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
!defined(NO_OLD_TLS))
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER))
|
||||
#define TEST_MEMIO_BUF_SZ (64 * 1024)
|
||||
struct test_memio_ctx
|
||||
{
|
||||
@@ -5206,6 +5205,51 @@ static WC_INLINE int test_memio_read_cb(WOLFSSL *ssl, char *data, int sz,
|
||||
return read_sz;
|
||||
}
|
||||
|
||||
static WC_INLINE int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s,
|
||||
int max_rounds, int *rounds)
|
||||
{
|
||||
byte handshake_complete = 0, hs_c = 0, hs_s = 0;
|
||||
int ret, err;
|
||||
|
||||
if (rounds != NULL)
|
||||
*rounds = 0;
|
||||
while (!handshake_complete && max_rounds > 0) {
|
||||
if (!hs_c) {
|
||||
ret = wolfSSL_connect(ssl_c);
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
hs_c = 1;
|
||||
}
|
||||
else {
|
||||
err = wolfSSL_get_error(ssl_c, ret);
|
||||
if (err != WOLFSSL_ERROR_WANT_READ &&
|
||||
err != WOLFSSL_ERROR_WANT_WRITE)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!hs_s) {
|
||||
ret = wolfSSL_accept(ssl_s);
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
hs_s = 1;
|
||||
}
|
||||
else {
|
||||
err = wolfSSL_get_error(ssl_c, ret);
|
||||
if (err != WOLFSSL_ERROR_WANT_READ &&
|
||||
err != WOLFSSL_ERROR_WANT_WRITE)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
handshake_complete = hs_c && hs_s;
|
||||
max_rounds--;
|
||||
if (rounds != NULL)
|
||||
*rounds = *rounds + 1;
|
||||
}
|
||||
|
||||
if (!handshake_complete)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WC_INLINE int test_memio_setup(struct test_memio_ctx *ctx,
|
||||
WOLFSSL_CTX **ctx_c, WOLFSSL_CTX **ctx_s, WOLFSSL **ssl_c, WOLFSSL **ssl_s,
|
||||
method_provider method_c, method_provider method_s)
|
||||
@@ -5224,6 +5268,9 @@ static WC_INLINE int test_memio_setup(struct test_memio_ctx *ctx,
|
||||
|
||||
ret = wolfSSL_CTX_use_certificate_file(*ctx_s, svrCertFile,
|
||||
WOLFSSL_FILETYPE_PEM);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return -1;
|
||||
ret = wolfSSL_CTX_load_verify_locations(*ctx_c, caCertFile, 0);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return -1;
|
||||
wolfSSL_SetIORecv(*ctx_c, test_memio_read_cb);
|
||||
|
Reference in New Issue
Block a user