SSL_set_num_tickets,
SSL_get_num_tickets,
SSL_CTX_set_num_tickets,
-SSL_CTX_get_num_tickets
+SSL_CTX_get_num_tickets,
+SSL_new_session_ticket
- control the number of TLSv1.3 session tickets that are issued
=head1 SYNOPSIS
size_t SSL_get_num_tickets(SSL *s);
int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets);
size_t SSL_CTX_get_num_tickets(SSL_CTX *ctx);
+ int SSL_new_session_ticket(SSL *s);
=head1 DESCRIPTION
SSL_verify_client_post_handshake() to update the number of tickets that will be
sent.
+To issue tickets after other events (such as application-layer changes),
+SSL_new_session_ticket() is used by a server application to request that a new
+ticket be sent when it is safe to do so. New tickets are only allowed to be
+sent in this manner after the initial handshake has completed, and only for TLS
+1.3 connections. The ticket generation and transmission are delayed until the
+server is starting a new write operation, so that it is bundled with other
+application data being written and properly aligned to a record boundary.
+SSL_new_session_ticket() can be called more than once to request additional
+tickets be sent; all such requests are queued and written together when it is
+safe to do so. Note that a successful return from SSL_new_session_ticket()
+indicates only that the request to send a ticket was processed, not that the
+ticket itself was sent. To be notified when the ticket itself is sent, a
+new-session callback can be registered with L<SSL_CTX_sess_set_new_cb(3)> that
+will be invoked as the ticket or tickets are generated.
+
SSL_CTX_get_num_tickets() and SSL_get_num_tickets() return the number of
tickets set by a previous call to SSL_CTX_set_num_tickets() or
SSL_set_num_tickets(), or 2 if no such call has been made.
=head1 RETURN VALUES
-SSL_CTX_set_num_tickets() and SSL_set_num_tickets() return 1 on success or 0 on
-failure.
+SSL_CTX_set_num_tickets(), SSL_set_num_tickets(), and
+SSL_new_session_ticket() return 1 on success or 0 on failure.
SSL_CTX_get_num_tickets() and SSL_get_num_tickets() return the number of tickets
that have been previously set.
=head1 HISTORY
-These functions were added in OpenSSL 1.1.1.
+SSL_new_session_ticket() was added in OpenSSL 3.0.0.
+SSL_set_num_tickets(), SSL_get_num_tickets(), SSL_CTX_set_num_tickets(), and
+SSL_CTX_get_num_tickets() were added in OpenSSL 1.1.1.
=head1 COPYRIGHT
int SSL_renegotiate(SSL *s);
int SSL_renegotiate_abbreviated(SSL *s);
__owur int SSL_renegotiate_pending(const SSL *s);
+int SSL_new_session_ticket(SSL *s);
int SSL_shutdown(SSL *s);
__owur int SSL_verify_client_post_handshake(SSL *s);
void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val);
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);
/*
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;
/* 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 */
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;
* 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;
}
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
/*
* 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);
}