summaryrefslogtreecommitdiffstats
path: root/ssl/statem/statem_srvr.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2018-01-31 17:26:46 +0000
committerMatt Caswell <matt@openssl.org>2018-05-17 16:48:25 +0100
commit9d0a8bb71e3e411e9183e635122f17c1429c4116 (patch)
tree9d6615d9cbf0690d8c0f5c95e1ddff074f52f20f /ssl/statem/statem_srvr.c
parent029c11c21fdd018ec51badaafd34118223055274 (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.c65
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);