Skip to content

Commit 9505105

Browse files
mattcaswellt8m
authored andcommitted
Move the Handshake read secret change earlier in the process for QUIC 0-RTT
On the server side we were changing the handshake rx secret a little late. This meant the application was forced to call SSL_do_handshake() again even if there was nothing to read in order to get the secret. We move it a little earlier int the process to avoid this. Fixes the issue described in: ngtcp2/ngtcp2#1582 (comment) Reviewed-by: Tim Hudson <[email protected]> Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> (Merged from openssl#27101)
1 parent c1d2778 commit 9505105

File tree

6 files changed

+29
-19
lines changed

6 files changed

+29
-19
lines changed

include/internal/statem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ typedef enum {
2626
WORK_FINISHED_STOP,
2727
/* We're done working move onto the next thing */
2828
WORK_FINISHED_CONTINUE,
29+
/* We're done writing, start reading (or vice versa) */
30+
WORK_FINISHED_SWAP,
2931
/* We're working on phase A */
3032
WORK_MORE_A,
3133
/* We're working on phase B */

ssl/ssl_lib.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4968,12 +4968,6 @@ int SSL_do_handshake(SSL *s)
49684968
}
49694969
}
49704970

4971-
if (ret == 1 && SSL_IS_QUIC_HANDSHAKE(sc) && !SSL_is_init_finished(s)) {
4972-
sc->rwstate = SSL_READING;
4973-
BIO_clear_retry_flags(SSL_get_rbio(s));
4974-
BIO_set_retry_read(SSL_get_rbio(s));
4975-
ret = 0;
4976-
}
49774971
return ret;
49784972
}
49794973

ssl/statem/statem.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -244,15 +244,6 @@ int ossl_statem_skip_early_data(SSL_CONNECTION *s)
244244
*/
245245
int ossl_statem_check_finish_init(SSL_CONNECTION *s, int sending)
246246
{
247-
int i = SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_READ;
248-
249-
if (s->server && SSL_NO_EOED(s) && s->ext.early_data == SSL_EARLY_DATA_ACCEPTED
250-
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_READING
251-
&& s->statem.hand_state == TLS_ST_EARLY_DATA) {
252-
s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
253-
if (!SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->change_cipher_state(s, i))
254-
return 0;
255-
}
256247
if (sending == -1) {
257248
if (s->statem.hand_state == TLS_ST_PENDING_EARLY_DATA_END
258249
|| s->statem.hand_state == TLS_ST_EARLY_DATA) {
@@ -737,6 +728,7 @@ static SUB_STATE_RETURN read_state_machine(SSL_CONNECTION *s)
737728
st->read_state = READ_STATE_HEADER;
738729
break;
739730

731+
case WORK_FINISHED_SWAP:
740732
case WORK_FINISHED_STOP:
741733
if (SSL_CONNECTION_IS_DTLS(s)) {
742734
dtls1_stop_timer(s);
@@ -882,6 +874,9 @@ static SUB_STATE_RETURN write_state_machine(SSL_CONNECTION *s)
882874
st->write_state = WRITE_STATE_SEND;
883875
break;
884876

877+
case WORK_FINISHED_SWAP:
878+
return SUB_STATE_FINISHED;
879+
885880
case WORK_FINISHED_STOP:
886881
return SUB_STATE_END_HANDSHAKE;
887882
}
@@ -955,6 +950,9 @@ static SUB_STATE_RETURN write_state_machine(SSL_CONNECTION *s)
955950
st->write_state = WRITE_STATE_TRANSITION;
956951
break;
957952

953+
case WORK_FINISHED_SWAP:
954+
return SUB_STATE_FINISHED;
955+
958956
case WORK_FINISHED_STOP:
959957
return SUB_STATE_END_HANDSHAKE;
960958
}

ssl/statem/statem_clnt.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,8 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s)
573573
return WRITE_TRAN_CONTINUE;
574574

575575
case TLS_ST_CW_CLNT_HELLO:
576-
if (s->early_data_state == SSL_EARLY_DATA_CONNECTING) {
576+
if (s->early_data_state == SSL_EARLY_DATA_CONNECTING
577+
&& !SSL_IS_QUIC_HANDSHAKE(s)) {
577578
/*
578579
* We are assuming this is a TLSv1.3 connection, although we haven't
579580
* actually selected a version yet.

ssl/statem/statem_srvr.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,21 @@ WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst)
839839
if (s->early_data_state != SSL_EARLY_DATA_ACCEPTING
840840
&& (s->s3.flags & TLS1_FLAGS_STATELESS) == 0)
841841
return WORK_FINISHED_CONTINUE;
842+
843+
/*
844+
* In QUIC with 0-RTT we just carry on when otherwise we would stop
845+
* to allow the server to read early data
846+
*/
847+
if (SSL_NO_EOED(s) && s->ext.early_data == SSL_EARLY_DATA_ACCEPTED
848+
&& s->early_data_state != SSL_EARLY_DATA_FINISHED_READING) {
849+
s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
850+
if (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE
851+
| SSL3_CHANGE_CIPHER_SERVER_READ)) {
852+
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
853+
return WORK_ERROR;
854+
}
855+
return WORK_FINISHED_SWAP;
856+
}
842857
/* Fall through */
843858

844859
case TLS_ST_OK:

test/sslapitest.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12969,15 +12969,15 @@ static int test_quic_tls_early_data(void)
1296912969
SSL_set_msg_callback(serverssl, assert_no_end_of_early_data);
1297012970
SSL_set_msg_callback(clientssl, assert_no_end_of_early_data);
1297112971

12972-
if (!TEST_int_eq(SSL_connect(clientssl), 0)
12973-
|| !TEST_int_eq(SSL_accept(serverssl), 0)
12972+
if (!TEST_int_eq(SSL_connect(clientssl), -1)
12973+
|| !TEST_int_eq(SSL_accept(serverssl), -1)
1297412974
|| !TEST_int_eq(SSL_get_early_data_status(serverssl), SSL_EARLY_DATA_ACCEPTED)
1297512975
|| !TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_WANT_READ)
1297612976
|| !TEST_int_eq(SSL_get_error(serverssl, 0), SSL_ERROR_WANT_READ))
1297712977
goto end;
1297812978

1297912979
/* Check the encryption levels are what we expect them to be */
12980-
if (!TEST_true(sdata.renc_level == OSSL_RECORD_PROTECTION_LEVEL_EARLY)
12980+
if (!TEST_true(sdata.renc_level == OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE)
1298112981
|| !TEST_true(sdata.wenc_level == OSSL_RECORD_PROTECTION_LEVEL_APPLICATION)
1298212982
|| !TEST_true(cdata.renc_level == OSSL_RECORD_PROTECTION_LEVEL_NONE)
1298312983
|| !TEST_true(cdata.wenc_level == OSSL_RECORD_PROTECTION_LEVEL_EARLY))

0 commit comments

Comments
 (0)