Adding NewSessionTicket.
We will now send tickets as a server and accept them as a
client. Correctly offering and resuming them in the handshake will be
implemented in a follow-up.
Now that we're actually processing draft 14 tickets, bump the draft
version.
Change-Id: I304320a29c4ffe564fa9c00642a4ace96ff8d871
Reviewed-on: https://boringssl-review.googlesource.com/8982
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/tls13_server.c b/ssl/tls13_server.c
index d844338..b15d56d 100644
--- a/ssl/tls13_server.c
+++ b/ssl/tls13_server.c
@@ -43,6 +43,8 @@
state_process_client_certificate,
state_process_client_certificate_verify,
state_process_client_finished,
+ state_send_new_session_ticket,
+ state_flush_new_session_ticket,
state_done,
};
@@ -506,10 +508,55 @@
}
ssl->method->received_flight(ssl);
- hs->state = state_done;
+ hs->state = state_send_new_session_ticket;
return ssl_hs_ok;
}
+static enum ssl_hs_wait_t do_send_new_session_ticket(SSL *ssl,
+ SSL_HANDSHAKE *hs) {
+ SSL_SESSION *session = ssl->s3->new_session;
+ session->ticket_lifetime_hint = session->timeout;
+ session->ticket_flags = SSL_TICKET_ALLOW_DHE_RESUMPTION;
+ if (!RAND_bytes((uint8_t *)&session->ticket_age_add,
+ sizeof(session->ticket_age_add))) {
+ return 0;
+ }
+ session->ticket_age_add_valid = 1;
+
+ CBB cbb, body, ticket;
+ if (!ssl->method->init_message(ssl, &cbb, &body,
+ SSL3_MT_NEW_SESSION_TICKET) ||
+ !CBB_add_u32(&body, session->ticket_lifetime_hint) ||
+ !CBB_add_u32(&body, session->ticket_flags) ||
+ !CBB_add_u32(&body, session->ticket_age_add) ||
+ !CBB_add_u16(&body, 0 /* no ticket extensions */) ||
+ !CBB_add_u16_length_prefixed(&body, &ticket) ||
+ !ssl_encrypt_ticket(ssl, &ticket, session) ||
+ !ssl->method->finish_message(ssl, &cbb)) {
+ CBB_cleanup(&cbb);
+ return ssl_hs_error;
+ }
+
+ hs->session_tickets_sent++;
+
+ hs->state = state_flush_new_session_ticket;
+ return ssl_hs_write_message;
+}
+
+/* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
+ * client makes several connections before getting a renewal. */
+static const int kNumTickets = 2;
+
+static enum ssl_hs_wait_t do_flush_new_session_ticket(SSL *ssl,
+ SSL_HANDSHAKE *hs) {
+ if (hs->session_tickets_sent >= kNumTickets) {
+ hs->state = state_done;
+ } else {
+ hs->state = state_send_new_session_ticket;
+ }
+ return ssl_hs_flush;
+}
+
enum ssl_hs_wait_t tls13_server_handshake(SSL *ssl) {
SSL_HANDSHAKE *hs = ssl->s3->hs;
@@ -562,6 +609,12 @@
case state_process_client_finished:
ret = do_process_client_finished(ssl, hs);
break;
+ case state_send_new_session_ticket:
+ ret = do_send_new_session_ticket(ssl, hs);
+ break;
+ case state_flush_new_session_ticket:
+ ret = do_flush_new_session_ticket(ssl, hs);
+ break;
case state_done:
ret = ssl_hs_ok;
break;