Skip to content

Commit

Permalink
Merge pull request wolfSSL#8475 from embhorn/gh8473
Browse files Browse the repository at this point in the history
Fix QUIC callback failure
  • Loading branch information
JacobBarthelmeh authored Feb 19, 2025
2 parents 268326d + 66ed35c commit 539056e
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/quic.c
Original file line number Diff line number Diff line change
Expand Up @@ -925,8 +925,12 @@ int wolfSSL_quic_forward_secrets(WOLFSSL* ssl, int ktype, int side)
goto cleanup;
}

ret = !ssl->quic.method->set_encryption_secrets(
ssl, level, rx_secret, tx_secret, ssl->specs.hash_size);
if(!ssl->quic.method->set_encryption_secrets(
ssl, level, rx_secret, tx_secret, ssl->specs.hash_size)) {
WOLFSSL_MSG("WOLFSSL_QUIC_FORWARD_SECRETS failed");
ret = WOLFSSL_FATAL_ERROR;
goto cleanup;
}

/* Having installed the secrets, any future read/write will happen
* at the level. Except early data, which is detected on the record
Expand Down
92 changes: 92 additions & 0 deletions tests/quic.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ static int dummy_set_encryption_secrets(WOLFSSL *ssl, WOLFSSL_ENCRYPTION_LEVEL l
return 1;
}

static int dummy_set_encryption_secrets_fail(WOLFSSL *ssl, WOLFSSL_ENCRYPTION_LEVEL level,
const uint8_t *read_secret,
const uint8_t *write_secret, size_t secret_len)
{
(void)ssl;
printf("QUIC_set_encryption_secrets(level=%d, length=%d, rx=%s, tx=%s)\n",
level, (int)secret_len, read_secret? "yes" : "no", write_secret? "yes" : "no");
return 0;
}

static int dummy_add_handshake_data(WOLFSSL *ssl, WOLFSSL_ENCRYPTION_LEVEL level,
const uint8_t *data, size_t len)
{
Expand Down Expand Up @@ -446,6 +456,13 @@ static WOLFSSL_QUIC_METHOD ctx_method = {
ctx_send_alert,
};

static WOLFSSL_QUIC_METHOD ctx_method_fail = {
dummy_set_encryption_secrets_fail,
ctx_add_handshake_data,
ctx_flush_flight,
ctx_send_alert,
};

static void QuicTestContext_init(QuicTestContext *tctx, WOLFSSL_CTX *ctx,
const char *name, int verbose)
{
Expand All @@ -472,6 +489,36 @@ static void QuicTestContext_init(QuicTestContext *tctx, WOLFSSL_CTX *ctx,
wolfSSL_set_quic_transport_version(tctx->ssl, 0);
wolfSSL_set_quic_transport_params(tctx->ssl, tp_params_c, sizeof(tp_params_c));
}
(void)ctx_method;
}

static void QuicTestContext_init_fail_cb(QuicTestContext *tctx, WOLFSSL_CTX *ctx,
const char *name, int verbose)
{
static const byte tp_params_c[] = {0, 1, 2, 3, 4, 5, 6, 7};
static const byte tp_params_s[] = {7, 6, 5, 4, 3, 2, 1, 0, 1};

AssertNotNull(tctx);
memset(tctx, 0, sizeof(*tctx));
tctx->name = name;
AssertNotNull((tctx->ssl = wolfSSL_new(ctx)));
tctx->verbose = verbose;
wolfSSL_set_app_data(tctx->ssl, tctx);
AssertTrue(wolfSSL_set_quic_method(tctx->ssl, &ctx_method_fail) == WOLFSSL_SUCCESS);
wolfSSL_set_verify(tctx->ssl, SSL_VERIFY_NONE, 0);
#ifdef HAVE_SESSION_TICKET
wolfSSL_UseSessionTicket(tctx->ssl);
wolfSSL_set_SessionTicket_cb(tctx->ssl, ctx_session_ticket_cb, NULL);
#endif
if (wolfSSL_is_server(tctx->ssl)) {
wolfSSL_set_quic_transport_version(tctx->ssl, 0);
wolfSSL_set_quic_transport_params(tctx->ssl, tp_params_s, sizeof(tp_params_s));
}
else {
wolfSSL_set_quic_transport_version(tctx->ssl, 0);
wolfSSL_set_quic_transport_params(tctx->ssl, tp_params_c, sizeof(tp_params_c));
}
(void)ctx_method;
}

static void QuicTestContext_free(QuicTestContext *tctx)
Expand Down Expand Up @@ -1193,6 +1240,50 @@ static int test_quic_server_hello(int verbose) {
return ret;
}

static int test_quic_server_hello_fail(int verbose) {
WOLFSSL_CTX *ctx_c, *ctx_s;
int ret = 0;
QuicTestContext tclient, tserver;
QuicConversation conv;

AssertNotNull(ctx_c = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
AssertNotNull(ctx_s = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile, WOLFSSL_FILETYPE_PEM));
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile, WOLFSSL_FILETYPE_PEM));

/* setup ssls */
QuicTestContext_init_fail_cb(&tclient, ctx_c, "client", verbose);
QuicTestContext_init(&tserver, ctx_s, "server", verbose);

/* connect */
QuicConversation_init(&conv, &tclient, &tserver);
QuicConversation_step(&conv, 0);
/* check established/missing secrets */
check_secrets(&tserver, wolfssl_encryption_initial, 0, 0);
check_secrets(&tserver, wolfssl_encryption_handshake,
DEFAULT_TLS_DIGEST_SZ, DEFAULT_TLS_DIGEST_SZ);
check_secrets(&tserver, wolfssl_encryption_application,
DEFAULT_TLS_DIGEST_SZ, DEFAULT_TLS_DIGEST_SZ);
check_secrets(&tclient, wolfssl_encryption_handshake, 0, 0);
/* feed the server data to the client. This is when the cb will fail */
QuicConversation_step(&conv, 1);
/* confirm failure to generate secrets */
{
int idx = (int)wolfssl_encryption_handshake;
AssertTrue(idx < 4);
AssertIntEQ(tclient.rx_secret_len[idx], 0);
AssertIntEQ(tclient.tx_secret_len[idx], 0);
}
QuicTestContext_free(&tclient);
QuicTestContext_free(&tserver);

wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
printf(" test_quic_server_hello_fail: %s\n", (ret == 0)? passed : failed);

return ret;
}

/* This has gotten a bit out of hand. */
#if (defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
(defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
Expand Down Expand Up @@ -1653,6 +1744,7 @@ int QuicTest(void)
if ((ret = test_quic_crypt()) != 0) goto leave;
if ((ret = test_quic_client_hello(verbose)) != 0) goto leave;
if ((ret = test_quic_server_hello(verbose)) != 0) goto leave;
if ((ret = test_quic_server_hello_fail(verbose)) != 0) goto leave;
#ifdef REALLY_HAVE_ALPN_AND_SNI
if ((ret = test_quic_alpn(verbose)) != 0) goto leave;
#endif /* REALLY_HAVE_ALPN_AND_SNI */
Expand Down

0 comments on commit 539056e

Please sign in to comment.