summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorBenjamin Kaduk <bkaduk@akamai.com>2020-03-16 11:25:58 -0700
committerBen Kaduk <kaduk@mit.edu>2020-05-01 15:10:11 -0700
commit3bfacb5fd4679812a7b9ec61d296b1add64669c0 (patch)
treebc10cebef57dc828c7da742dada9a3e05910884a /ssl
parent6250282f7fc37c5903d051174a69053a80e1b1bd (diff)
Add SSL_new_session_ticket() API
This API requests that the TLS stack generate a (TLS 1.3) NewSessionTicket message the next time it is safe to do so (i.e., we do not have other data pending write, which could be mid-record). For efficiency, defer actually generating/writing the ticket until there is other data to write, to avoid producing server-to-client traffic when not needed. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11416)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/record/rec_layer_s3.c8
-rw-r--r--ssl/ssl_lib.c9
-rw-r--r--ssl/ssl_local.h2
-rw-r--r--ssl/statem/statem_srvr.c16
4 files changed, 29 insertions, 6 deletions
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index d4198917d0..bceac72051 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -384,10 +384,12 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len,
s->rlayer.wnum = 0;
/*
- * If we are supposed to be sending a KeyUpdate then go into init unless we
- * have writes pending - in which case we should finish doing that first.
+ * If we are supposed to be sending a KeyUpdate or NewSessionTicket then go
+ * into init unless we have writes pending - in which case we should finish
+ * doing that first.
*/
- if (wb->left == 0 && s->key_update != SSL_KEY_UPDATE_NONE)
+ if (wb->left == 0 && (s->key_update != SSL_KEY_UPDATE_NONE
+ || s->ext.extra_tickets_expected > 0))
ossl_statem_set_in_init(s, 1);
/*
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 63cbb3d904..fde726e0ba 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2303,6 +2303,15 @@ int SSL_renegotiate_pending(const SSL *s)
return (s->renegotiate != 0);
}
+int SSL_new_session_ticket(SSL *s)
+{
+ if (SSL_in_init(s) || SSL_IS_FIRST_HANDSHAKE(s) || !s->server
+ || !SSL_IS_TLS13(s))
+ return 0;
+ s->ext.extra_tickets_expected++;
+ return 1;
+}
+
long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
{
long l;
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 21bf482bef..de7e9fde48 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -1539,6 +1539,8 @@ struct ssl_st {
/* RFC4507 session ticket expected to be received or sent */
int ticket_expected;
+ /* TLS 1.3 tickets requested by the application. */
+ int extra_tickets_expected;
# ifndef OPENSSL_NO_EC
size_t ecpointformats_len;
/* our list */
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index b11363db7a..d1d86ea5e6 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -441,6 +441,10 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
st->hand_state = TLS_ST_SW_CERT_REQ;
return WRITE_TRAN_CONTINUE;
}
+ if (s->ext.extra_tickets_expected > 0) {
+ st->hand_state = TLS_ST_SW_SESSION_TICKET;
+ return WRITE_TRAN_CONTINUE;
+ }
/* Try to read from the client instead */
return WRITE_TRAN_FINISHED;
@@ -531,7 +535,9 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
* Following an initial handshake we send the number of tickets we have
* been configured for.
*/
- if (s->hit || s->num_tickets <= s->sent_tickets) {
+ if (!SSL_IS_FIRST_HANDSHAKE(s) && s->ext.extra_tickets_expected > 0) {
+ return WRITE_TRAN_CONTINUE;
+ } else if (s->hit || s->num_tickets <= s->sent_tickets) {
/* We've written enough tickets out. */
st->hand_state = TLS_ST_OK;
}
@@ -727,7 +733,8 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst)
return WORK_FINISHED_CONTINUE;
case TLS_ST_SW_SESSION_TICKET:
- if (SSL_IS_TLS13(s) && s->sent_tickets == 0) {
+ if (SSL_IS_TLS13(s) && s->sent_tickets == 0
+ && s->ext.extra_tickets_expected == 0) {
/*
* Actually this is the end of the handshake, but we're going
* straight into writing the session ticket out. So we finish off
@@ -4161,10 +4168,13 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
/*
* Increment both |sent_tickets| and |next_ticket_nonce|. |sent_tickets|
* gets reset to 0 if we send more tickets following a post-handshake
- * auth, but |next_ticket_nonce| does not.
+ * auth, but |next_ticket_nonce| does not. If we're sending extra
+ * tickets, decrement the count of pending extra tickets.
*/
s->sent_tickets++;
s->next_ticket_nonce++;
+ if (s->ext.extra_tickets_expected > 0)
+ s->ext.extra_tickets_expected--;
ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
}