diff options
author | Matt Caswell <matt@openssl.org> | 2018-01-31 17:26:46 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2018-05-17 16:48:25 +0100 |
commit | 9d0a8bb71e3e411e9183e635122f17c1429c4116 (patch) | |
tree | 9d6615d9cbf0690d8c0f5c95e1ddff074f52f20f /ssl/statem/statem_srvr.c | |
parent | 029c11c21fdd018ec51badaafd34118223055274 (diff) |
Enable the ability to set the number of TLSv1.3 session tickets sent
We send a session ticket automatically in TLSv1.3 at the end of the
handshake. This commit provides the ability to set how many tickets should
be sent. By default this is one.
Fixes #4978
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5227)
Diffstat (limited to 'ssl/statem/statem_srvr.c')
-rw-r--r-- | ssl/statem/statem_srvr.c | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 22786bed13..dfeba173a7 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -480,13 +480,9 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) case TLS_ST_SR_FINISHED: /* * Technically we have finished the handshake at this point, but we're - * going to remain "in_init" for now and write out the session ticket + * going to remain "in_init" for now and write out any session tickets * immediately. - * TODO(TLS1.3): Perhaps we need to be able to control this behaviour - * and give the application the opportunity to delay sending the - * session ticket? */ - st->hand_state = TLS_ST_SW_SESSION_TICKET; if (s->post_handshake_auth == SSL_PHA_REQUESTED) { s->post_handshake_auth = SSL_PHA_EXT_RECEIVED; } else if (!s->ext.ticket_expected) { @@ -495,7 +491,12 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) * handshake at this point. */ st->hand_state = TLS_ST_OK; + return WRITE_TRAN_CONTINUE; } + if (s->num_tickets > s->sent_tickets) + st->hand_state = TLS_ST_SW_SESSION_TICKET; + else + st->hand_state = TLS_ST_OK; return WRITE_TRAN_CONTINUE; case TLS_ST_SR_KEY_UPDATE: @@ -507,7 +508,14 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) case TLS_ST_SW_KEY_UPDATE: case TLS_ST_SW_SESSION_TICKET: - st->hand_state = TLS_ST_OK; + /* In a resumption we only ever send a maximum of one new ticket. + * Following an initial handshake we send the number of tickets we have + * been configured for. + */ + if (s->hit || s->num_tickets <= s->sent_tickets) { + /* We've written enough tickets out. */ + st->hand_state = TLS_ST_OK; + } return WRITE_TRAN_CONTINUE; } } @@ -3743,21 +3751,41 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) } age_add_u; if (SSL_IS_TLS13(s)) { - if (s->post_handshake_auth != SSL_PHA_EXT_RECEIVED) { - void (*cb) (const SSL *ssl, int type, int val) = NULL; + void (*cb) (const SSL *ssl, int type, int val) = NULL; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { /* - * This is the first session ticket we've sent. In the state - * machine we "cheated" and tacked this onto the end of the first - * handshake. From an info callback perspective this should appear - * like the start of a new handshake. + * We don't start and stop the handshake in between each ticket when + * sending more than one - but it should appear that way to the info + * callback. */ - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); + if (s->sent_tickets != 0) { + ossl_statem_set_in_init(s, 0); + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + ossl_statem_set_in_init(s, 1); + } + cb(s, SSL_CB_HANDSHAKE_START, 1); + } + /* + * If we already sent one NewSessionTicket then we need to take a copy + * of it and create a new session from it. + */ + if (s->sent_tickets != 0) { + SSL_SESSION *new_sess = ssl_session_dup(s->session, 0); + + if (new_sess == NULL) { + /* SSLfatal already called */ + goto err; + } + + SSL_SESSION_free(s->session); + s->session = new_sess; } if (!ssl_generate_session_id(s, s->session)) { @@ -3968,6 +3996,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) /* SSLfatal() already called */ goto err; } + s->sent_tickets++; } EVP_CIPHER_CTX_free(ctx); HMAC_CTX_free(hctx); |