Skip to content

Commit c9e9e0f

Browse files
Merge pull request #6704 from icing/session-copy-on-write
Updating a shared session objects needs to do copy on write
2 parents 2f2dddd + 8ce71cc commit c9e9e0f

6 files changed

Lines changed: 129 additions & 14 deletions

File tree

src/internal.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27456,6 +27456,20 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
2745627456
/* client only parts */
2745727457
#ifndef NO_WOLFSSL_CLIENT
2745827458

27459+
int HaveUniqueSessionObj(WOLFSSL* ssl)
27460+
{
27461+
if (ssl->session->ref.count > 1) {
27462+
WOLFSSL_SESSION* newSession = wolfSSL_SESSION_dup(ssl->session);
27463+
if (newSession == NULL) {
27464+
WOLFSSL_MSG("Session duplicate failed");
27465+
return 0;
27466+
}
27467+
wolfSSL_FreeSession(ssl->ctx, ssl->session);
27468+
ssl->session = newSession;
27469+
}
27470+
return 1;
27471+
}
27472+
2745927473
#ifndef WOLFSSL_NO_TLS12
2746027474

2746127475
/* handle generation of client_hello (1) */
@@ -28295,6 +28309,11 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
2829528309
else {
2829628310
if (DSH_CheckSessionId(ssl)) {
2829728311
if (SetCipherSpecs(ssl) == 0) {
28312+
if (!HaveUniqueSessionObj(ssl)) {
28313+
WOLFSSL_MSG("Unable to have unique session object");
28314+
WOLFSSL_ERROR_VERBOSE(MEMORY_ERROR);
28315+
return MEMORY_ERROR;
28316+
}
2829828317

2829928318
XMEMCPY(ssl->arrays->masterSecret,
2830028319
ssl->session->masterSecret, SECRET_LEN);
@@ -31810,6 +31829,9 @@ int SendCertificateVerify(WOLFSSL* ssl)
3181031829
#ifdef HAVE_SESSION_TICKET
3181131830
int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length)
3181231831
{
31832+
if (!HaveUniqueSessionObj(ssl))
31833+
return MEMORY_ERROR;
31834+
3181331835
/* Free old dynamic ticket if we already had one */
3181431836
if (ssl->session->ticketLenAlloc > 0) {
3181531837
XFREE(ssl->session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);

src/ssl.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14173,21 +14173,15 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
1417314173
if (ssl->session == session) {
1417414174
WOLFSSL_MSG("ssl->session and session same");
1417514175
}
14176-
else
14177-
#ifdef HAVE_STUNNEL
14178-
/* stunnel depends on the ex_data not being duplicated. Copy OpenSSL
14179-
* behaviour for now. */
14180-
if (session->type != WOLFSSL_SESSION_TYPE_CACHE) {
14176+
else if (session->type != WOLFSSL_SESSION_TYPE_CACHE) {
1418114177
if (wolfSSL_SESSION_up_ref(session) == WOLFSSL_SUCCESS) {
1418214178
wolfSSL_FreeSession(ssl->ctx, ssl->session);
1418314179
ssl->session = session;
1418414180
}
1418514181
else
1418614182
ret = WOLFSSL_FAILURE;
1418714183
}
14188-
else
14189-
#endif
14190-
{
14184+
else {
1419114185
ret = wolfSSL_DupSession(session, ssl->session, 0);
1419214186
if (ret != WOLFSSL_SUCCESS)
1419314187
WOLFSSL_MSG("Session duplicate failed");
@@ -20607,7 +20601,6 @@ int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
2060720601

2060820602
WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
2060920603
{
20610-
#ifdef HAVE_EXT_CACHE
2061120604
WOLFSSL_SESSION* copy;
2061220605

2061320606
WOLFSSL_ENTER("wolfSSL_SESSION_dup");
@@ -20630,11 +20623,6 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
2063020623
copy = NULL;
2063120624
}
2063220625
return copy;
20633-
#else
20634-
WOLFSSL_MSG("wolfSSL_SESSION_dup feature not compiled in");
20635-
(void)session;
20636-
return NULL;
20637-
#endif /* HAVE_EXT_CACHE */
2063820626
}
2063920627

2064020628
void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)

src/tls13.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3762,6 +3762,12 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
37623762
if (psk == NULL)
37633763
return BAD_FUNC_ARG;
37643764

3765+
if (!HaveUniqueSessionObj(ssl)) {
3766+
WOLFSSL_MSG("Unable to have unique session object");
3767+
WOLFSSL_ERROR_VERBOSE(MEMORY_ERROR);
3768+
return MEMORY_ERROR;
3769+
}
3770+
37653771
suite[0] = ssl->options.cipherSuite0;
37663772
suite[1] = ssl->options.cipherSuite;
37673773

tests/api.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5855,7 +5855,9 @@ static int test_ssl_memio_do_handshake(test_ssl_memio_ctx* ctx, int max_rounds,
58555855
}
58565856
while ((!handshake_complete) && (max_rounds > 0)) {
58575857
if (!hs_c) {
5858+
wolfSSL_SetLoggingPrefix("client");
58585859
ret = wolfSSL_connect(ctx->c_ssl);
5860+
wolfSSL_SetLoggingPrefix(NULL);
58595861
if (ret == WOLFSSL_SUCCESS) {
58605862
hs_c = 1;
58615863
}
@@ -5872,7 +5874,9 @@ static int test_ssl_memio_do_handshake(test_ssl_memio_ctx* ctx, int max_rounds,
58725874
}
58735875
}
58745876
if (!hs_s) {
5877+
wolfSSL_SetLoggingPrefix("server");
58755878
ret = wolfSSL_accept(ctx->s_ssl);
5879+
wolfSSL_SetLoggingPrefix(NULL);
58765880
if (ret == WOLFSSL_SUCCESS) {
58775881
hs_s = 1;
58785882
}
@@ -5921,15 +5925,19 @@ static int test_ssl_memio_read_write(test_ssl_memio_ctx* ctx)
59215925
msglen_s = ctx->s_msglen;
59225926
}
59235927

5928+
wolfSSL_SetLoggingPrefix("client");
59245929
ExpectIntEQ(wolfSSL_write(ctx->c_ssl, msg_c, msglen_c), msglen_c);
5930+
wolfSSL_SetLoggingPrefix("server");
59255931
ExpectIntGT(idx = wolfSSL_read(ctx->s_ssl, input, sizeof(input) - 1), 0);
59265932
if (idx >= 0) {
59275933
input[idx] = '\0';
59285934
}
59295935
ExpectIntGT(fprintf(stderr, "Client message: %s\n", input), 0);
59305936
ExpectIntEQ(wolfSSL_write(ctx->s_ssl, msg_s, msglen_s), msglen_s);
59315937
ctx->s_cb.return_code = EXPECT_RESULT();
5938+
wolfSSL_SetLoggingPrefix("client");
59325939
ExpectIntGT(idx = wolfSSL_read(ctx->c_ssl, input, sizeof(input) - 1), 0);
5940+
wolfSSL_SetLoggingPrefix(NULL);
59335941
if (idx >= 0) {
59345942
input[idx] = '\0';
59355943
}
@@ -64445,6 +64453,91 @@ static int test_session_ticket_no_id(void)
6444564453
}
6444664454
#endif
6444764455

64456+
static int test_session_ticket_hs_update(void)
64457+
{
64458+
EXPECT_DECLS;
64459+
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
64460+
defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
64461+
struct test_memio_ctx test_ctx;
64462+
struct test_memio_ctx test_ctx2;
64463+
struct test_memio_ctx test_ctx3;
64464+
WOLFSSL_CTX *ctx_c = NULL;
64465+
WOLFSSL_CTX *ctx_s = NULL;
64466+
WOLFSSL *ssl_c = NULL;
64467+
WOLFSSL *ssl_c2 = NULL;
64468+
WOLFSSL *ssl_c3 = NULL;
64469+
WOLFSSL *ssl_s = NULL;
64470+
WOLFSSL *ssl_s2 = NULL;
64471+
WOLFSSL *ssl_s3 = NULL;
64472+
WOLFSSL_SESSION *sess = NULL;
64473+
byte read_data[1];
64474+
64475+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
64476+
XMEMSET(&test_ctx2, 0, sizeof(test_ctx2));
64477+
XMEMSET(&test_ctx3, 0, sizeof(test_ctx3));
64478+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
64479+
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
64480+
64481+
/* Generate tickets */
64482+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
64483+
wolfSSL_SetLoggingPrefix("client");
64484+
/* Read the ticket msg */
64485+
ExpectIntEQ(wolfSSL_read(ssl_c, read_data, sizeof(read_data)),
64486+
WOLFSSL_FATAL_ERROR);
64487+
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
64488+
WOLFSSL_ERROR_WANT_READ);
64489+
wolfSSL_SetLoggingPrefix(NULL);
64490+
64491+
ExpectIntEQ(test_memio_setup(&test_ctx2, &ctx_c, &ctx_s, &ssl_c2, &ssl_s2,
64492+
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
64493+
ExpectIntEQ(test_memio_setup(&test_ctx3, &ctx_c, &ctx_s, &ssl_c3, &ssl_s3,
64494+
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
64495+
64496+
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
64497+
ExpectIntEQ(wolfSSL_set_session(ssl_c2, sess), WOLFSSL_SUCCESS);
64498+
ExpectIntEQ(wolfSSL_set_session(ssl_c3, sess), WOLFSSL_SUCCESS);
64499+
64500+
wolfSSL_SetLoggingPrefix("client");
64501+
/* Exchange intial flights for the second connection */
64502+
ExpectIntEQ(wolfSSL_connect(ssl_c2), WOLFSSL_FATAL_ERROR);
64503+
ExpectIntEQ(wolfSSL_get_error(ssl_c2, WOLFSSL_FATAL_ERROR),
64504+
WOLFSSL_ERROR_WANT_READ);
64505+
wolfSSL_SetLoggingPrefix(NULL);
64506+
wolfSSL_SetLoggingPrefix("server");
64507+
ExpectIntEQ(wolfSSL_accept(ssl_s2), WOLFSSL_FATAL_ERROR);
64508+
ExpectIntEQ(wolfSSL_get_error(ssl_s2, WOLFSSL_FATAL_ERROR),
64509+
WOLFSSL_ERROR_WANT_READ);
64510+
wolfSSL_SetLoggingPrefix(NULL);
64511+
64512+
/* Complete third connection so that new tickets are exchanged */
64513+
ExpectIntEQ(test_memio_do_handshake(ssl_c3, ssl_s3, 10, NULL), 0);
64514+
/* Read the ticket msg */
64515+
wolfSSL_SetLoggingPrefix("client");
64516+
ExpectIntEQ(wolfSSL_read(ssl_c3, read_data, sizeof(read_data)),
64517+
WOLFSSL_FATAL_ERROR);
64518+
ExpectIntEQ(wolfSSL_get_error(ssl_c3, WOLFSSL_FATAL_ERROR),
64519+
WOLFSSL_ERROR_WANT_READ);
64520+
wolfSSL_SetLoggingPrefix(NULL);
64521+
64522+
/* Complete second connection */
64523+
ExpectIntEQ(test_memio_do_handshake(ssl_c2, ssl_s2, 10, NULL), 0);
64524+
64525+
ExpectIntEQ(wolfSSL_session_reused(ssl_c2), 1);
64526+
ExpectIntEQ(wolfSSL_session_reused(ssl_c3), 1);
64527+
64528+
wolfSSL_free(ssl_c);
64529+
wolfSSL_free(ssl_c2);
64530+
wolfSSL_free(ssl_c3);
64531+
wolfSSL_free(ssl_s);
64532+
wolfSSL_free(ssl_s2);
64533+
wolfSSL_free(ssl_s3);
64534+
wolfSSL_CTX_free(ctx_c);
64535+
wolfSSL_CTX_free(ctx_s);
64536+
wolfSSL_SESSION_free(sess);
64537+
#endif
64538+
return EXPECT_RESULT();
64539+
}
64540+
6444864541
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
6444964542
defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)
6445064543
static void test_dtls_downgrade_scr_server_ctx_ready_server(WOLFSSL_CTX* ctx)
@@ -65826,6 +65919,7 @@ TEST_CASE testCases[] = {
6582665919
TEST_DECL(test_TLSX_CA_NAMES_bad_extension),
6582765920
TEST_DECL(test_dtls_1_0_hvr_downgrade),
6582865921
TEST_DECL(test_session_ticket_no_id),
65922+
TEST_DECL(test_session_ticket_hs_update),
6582965923
TEST_DECL(test_dtls_downgrade_scr_server),
6583065924
TEST_DECL(test_dtls_downgrade_scr),
6583165925
/* This test needs to stay at the end to clean up any caches allocated. */

tests/utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,9 @@ int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s,
207207
*rounds = 0;
208208
while (!handshake_complete && max_rounds > 0) {
209209
if (!hs_c) {
210+
wolfSSL_SetLoggingPrefix("client");
210211
ret = wolfSSL_connect(ssl_c);
212+
wolfSSL_SetLoggingPrefix(NULL);
211213
if (ret == WOLFSSL_SUCCESS) {
212214
hs_c = 1;
213215
}
@@ -219,7 +221,9 @@ int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s,
219221
}
220222
}
221223
if (!hs_s) {
224+
wolfSSL_SetLoggingPrefix("server");
222225
ret = wolfSSL_accept(ssl_s);
226+
wolfSSL_SetLoggingPrefix(NULL);
223227
if (ret == WOLFSSL_SUCCESS) {
224228
hs_s = 1;
225229
}

wolfssl/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6209,6 +6209,7 @@ WOLFSSL_LOCAL void DoCertFatalAlert(WOLFSSL* ssl, int ret);
62096209
WOLFSSL_LOCAL int cipherExtraData(WOLFSSL* ssl);
62106210

62116211
#ifndef NO_WOLFSSL_CLIENT
6212+
WOLFSSL_LOCAL int HaveUniqueSessionObj(WOLFSSL* ssl);
62126213
WOLFSSL_LOCAL int SendClientHello(WOLFSSL* ssl);
62136214
WOLFSSL_LOCAL int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
62146215
word32 size);

0 commit comments

Comments
 (0)