forked from wolfSSL/wolfssl
QUIC session resumption and early data handshake handling.
In test with ngtcp2 example client using openssl, session resumption against a QUIC wolfssl server failed. The error was tracked down to wolfSSL believing EaryData needs to be handled and returning SUCCESS from wolfSSL_SSL_do_handshake() after the server Finished had been sent. However the handshake was not complete and ngtcp2 invoked the post_handshake processing for new data arriving from the client. This failed a check in post processing that the ssl->handShakeState actually was HANDSHAKE_DONE. The workaround in this PR repeats do_handshake until the ssl state acually says it is complete. This way, session resumption works. Either this alternative do_handshake() is merged for QUIC protocol hanlders. Or we need to fix the 'normal' do_handshake() to no return SUCCESS when early data is expected on a QUIC WOLFSSL.
This commit is contained in:
35
src/quic.c
35
src/quic.c
@ -554,6 +554,37 @@ void wolfSSL_set_quic_early_data_enabled(WOLFSSL* ssl, int enabled)
|
||||
}
|
||||
#endif /* WOLFSSL_EARLY_DATA */
|
||||
|
||||
int wolfSSL_quic_do_handshake(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_quic_do_handshake");
|
||||
|
||||
if (!wolfSSL_is_quic(ssl)) {
|
||||
WOLFSSL_MSG("WOLFSSL_QUIC_DO_HANDSHAKE not a QUIC SSL");
|
||||
ret = WOLFSSL_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
while (ssl->options.handShakeState != HANDSHAKE_DONE) {
|
||||
/* Peculiar: do_handshake() is successful, but the state
|
||||
* indicates that we are not DONE. This seems to happen
|
||||
* when resuming sessions and an EARLY_DATA indicator
|
||||
* is presented by the client.
|
||||
* Theory: wolfSSL expects the APP to read the early data
|
||||
* and silently continues the handshake when the EndOfEarlyData
|
||||
* and the client Finished arrives.
|
||||
* This confuses the QUIC state handling.
|
||||
*/
|
||||
ret = wolfSSL_SSL_do_handshake(ssl);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
WOLFSSL_LEAVE("wolfSSL_quic_do_handshake", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wolfSSL_quic_read_write(WOLFSSL* ssl)
|
||||
{
|
||||
@ -568,7 +599,7 @@ int wolfSSL_quic_read_write(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
if (ssl->options.handShakeState != HANDSHAKE_DONE) {
|
||||
ret = wolfSSL_SSL_do_handshake(ssl);
|
||||
ret = wolfSSL_quic_do_handshake(ssl);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
goto cleanup;
|
||||
}
|
||||
@ -603,6 +634,8 @@ int wolfSSL_process_quic_post_handshake(WOLFSSL* ssl)
|
||||
|
||||
if (ssl->options.handShakeState != HANDSHAKE_DONE) {
|
||||
WOLFSSL_MSG("WOLFSSL_QUIC_POST_HS handshake is not done yet");
|
||||
fprintf(stderr, "WOLFSSL_QUIC_POST_HS, handShakeState is %d\n",
|
||||
ssl->options.handShakeState);
|
||||
ret = WOLFSSL_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -8063,6 +8063,13 @@ int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
ssl->earlyData = done_early_data;
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS13 && WOLFSSL_EARLY_DATA */
|
||||
#if defined(WOLFSSL_QUIC) && defined(WOLFSSL_EARLY_DATA)
|
||||
if (WOLFSSL_IS_QUIC(ssl) && ssl->earlyData > early_data_ext) {
|
||||
/* QUIC has no EndOfearlydata messages. We stop processing EarlyData
|
||||
as soon we receive the client's finished message */
|
||||
ssl->earlyData = done_early_data;
|
||||
}
|
||||
#endif /* WOLFSSL_QUIC && WOLFSSL_EARLY_DATA */
|
||||
|
||||
WOLFSSL_LEAVE("DoTls13Finished", 0);
|
||||
WOLFSSL_END(WC_FUNC_FINISHED_DO);
|
||||
|
@ -189,6 +189,9 @@ WOLFSSL_API
|
||||
int wolfSSL_provide_quic_data(WOLFSSL* ssl, WOLFSSL_ENCRYPTION_LEVEL level,
|
||||
const uint8_t* data, size_t len);
|
||||
|
||||
WOLFSSL_API
|
||||
int wolfSSL_quic_do_handshake(WOLFSSL* ssl);
|
||||
|
||||
/**
|
||||
* Process any CRYPTO data added post-handshake.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user