summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-07-02 10:11:41 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-07-12 11:56:58 +0200
commite1326209aa7160e1332cf571a8eb8c2ccfd7369d (patch)
tree51fd8ebb9da0861fd0420cdf9947a999eb65ad47
parent40b5e30494230f1e87d1622f14cf65cce5ba3bc9 (diff)
downloadgnutls-e1326209aa7160e1332cf571a8eb8c2ccfd7369d.tar.gz
gnutls_session_ticket_send: allow sending multiple tickets in one go
This allows combining the tickets in a single record message when possible. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/handshake-tls13.c10
-rw-r--r--lib/handshake.c14
-rw-r--r--lib/handshake.h5
-rw-r--r--lib/includes/gnutls/gnutls.h.in2
-rw-r--r--lib/tls13/session_ticket.c104
-rw-r--r--lib/tls13/session_ticket.h2
6 files changed, 83 insertions, 54 deletions
diff --git a/lib/handshake-tls13.c b/lib/handshake-tls13.c
index 8a8ae52774..631665d7a7 100644
--- a/lib/handshake-tls13.c
+++ b/lib/handshake-tls13.c
@@ -390,7 +390,7 @@ int _gnutls13_handshake_server(gnutls_session_t session)
/* fall through */
case STATE112:
- ret = _gnutls13_send_session_ticket(session, AGAIN(STATE112));
+ ret = _gnutls13_send_session_ticket(session, 1, AGAIN(STATE112));
STATE = STATE112;
IMED_RET("send session ticket", ret, 0);
@@ -499,6 +499,7 @@ _gnutls13_recv_async_handshake(gnutls_session_t session, gnutls_buffer_st *buf)
/**
* gnutls_session_ticket_send:
* @session: is a #gnutls_session_t type.
+ * @nr: the number of tickets to send; must be a positive integer
* @flags: must be zero
*
* Sends a fresh session ticket to the peer. This is relevant only
@@ -507,7 +508,7 @@ _gnutls13_recv_async_handshake(gnutls_session_t session, gnutls_buffer_st *buf)
*
* Returns: %GNUTLS_E_SUCCESS on success, or a negative error code.
**/
-int gnutls_session_ticket_send(gnutls_session_t session, unsigned flags)
+int gnutls_session_ticket_send(gnutls_session_t session, unsigned nr, unsigned flags)
{
int ret = 0;
const version_entry_st *vers = get_version(session);
@@ -515,6 +516,9 @@ int gnutls_session_ticket_send(gnutls_session_t session, unsigned flags)
if (!vers->tls13_sem || session->security_parameters.entity == GNUTLS_CLIENT)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ if (nr == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
switch (TICKET_STATE) {
case TICKET_STATE0:
ret = _gnutls_io_write_flush(session);
@@ -526,7 +530,7 @@ int gnutls_session_ticket_send(gnutls_session_t session, unsigned flags)
/* fall through */
case TICKET_STATE1:
ret =
- _gnutls13_send_session_ticket(session, TICKET_STATE==TICKET_STATE1?1:0);
+ _gnutls13_send_session_ticket(session, nr, TICKET_STATE==TICKET_STATE1?1:0);
TICKET_STATE = TICKET_STATE1;
if (ret < 0) {
gnutls_assert();
diff --git a/lib/handshake.c b/lib/handshake.c
index dd2e02908c..5feaed99fd 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -1154,14 +1154,21 @@ int _gnutls_call_hook_func(gnutls_session_t session,
(t == GNUTLS_HANDSHAKE_HELLO_REQUEST || t == GNUTLS_HANDSHAKE_KEY_UPDATE || \
(t == GNUTLS_HANDSHAKE_NEW_SESSION_TICKET && v->tls13_sem))
+int
+_gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel,
+ gnutls_handshake_description_t type)
+{
+ return _gnutls_send_handshake2(session, bufel, type, 0);
+}
+
/* This function sends a handshake message of type 'type' containing the
* data specified here. If the previous _gnutls_send_handshake() returned
* GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
* (until it returns ok), with NULL parameters.
*/
int
-_gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel,
- gnutls_handshake_description_t type)
+_gnutls_send_handshake2(gnutls_session_t session, mbuffer_st * bufel,
+ gnutls_handshake_description_t type, unsigned queue_only)
{
int ret;
uint8_t *data;
@@ -1244,6 +1251,9 @@ _gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel,
return ret;
}
+ if (queue_only)
+ return 0;
+
/* Decide when to cache and when to send */
if (vers && vers->tls13_sem) {
diff --git a/lib/handshake.h b/lib/handshake.h
index 465ee03b80..390f5034f9 100644
--- a/lib/handshake.h
+++ b/lib/handshake.h
@@ -61,6 +61,11 @@ int _gnutls_recv_hello_request(gnutls_session_t session, void *data,
int _gnutls_recv_handshake(gnutls_session_t session,
gnutls_handshake_description_t type,
unsigned int optional, gnutls_buffer_st * buf);
+
+int
+_gnutls_send_handshake2(gnutls_session_t session, mbuffer_st * bufel,
+ gnutls_handshake_description_t type, unsigned queue_only);
+
int _gnutls_generate_session_id(uint8_t * session_id, uint8_t * len);
int _gnutls_gen_server_random(gnutls_session_t session, int version);
void _gnutls_set_client_random(gnutls_session_t session, uint8_t * rnd);
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index b675035f3e..f57d0d7cc7 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1480,7 +1480,7 @@ int gnutls_session_ticket_enable_client(gnutls_session_t session);
int gnutls_session_ticket_enable_server(gnutls_session_t session,
const gnutls_datum_t * key);
-int gnutls_session_ticket_send(gnutls_session_t session, unsigned flags);
+int gnutls_session_ticket_send(gnutls_session_t session, unsigned nr, unsigned flags);
/* SRTP, RFC 5764 */
diff --git a/lib/tls13/session_ticket.c b/lib/tls13/session_ticket.c
index 77edbcda91..184c0ac271 100644
--- a/lib/tls13/session_ticket.c
+++ b/lib/tls13/session_ticket.c
@@ -227,12 +227,13 @@ generate_session_ticket(gnutls_session_t session, tls13_ticket_t *ticket)
return 0;
}
-int _gnutls13_send_session_ticket(gnutls_session_t session, unsigned again)
+int _gnutls13_send_session_ticket(gnutls_session_t session, unsigned nr, unsigned again)
{
int ret = 0;
mbuffer_st *bufel = NULL;
gnutls_buffer_st buf;
tls13_ticket_t ticket;
+ unsigned i;
/* Client does not send a NewSessionTicket */
if (unlikely(session->security_parameters.entity == GNUTLS_CLIENT))
@@ -249,70 +250,79 @@ int _gnutls13_send_session_ticket(gnutls_session_t session, unsigned again)
return gnutls_assert_val(0);
if (again == 0) {
- memset(&ticket, 0, sizeof(tls13_ticket_t));
-
- ret = generate_session_ticket(session, &ticket);
- if (ret < 0) {
- if (ret == GNUTLS_E_INT_RET_0) {
- return gnutls_assert_val(0);
+ for (i=0;i<nr;i++) {
+ memset(&ticket, 0, sizeof(tls13_ticket_t));
+ bufel = NULL;
+
+ ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = generate_session_ticket(session, &ticket);
+ if (ret < 0) {
+ if (ret == GNUTLS_E_INT_RET_0) {
+ ret = gnutls_assert_val(0);
+ goto cleanup;
+ }
+ gnutls_assert();
+ goto cleanup;
}
- return gnutls_assert_val(ret);
- }
+ ret = _gnutls_buffer_append_prefix(&buf, 32, ticket.lifetime);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
- ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
+ ret = _gnutls_buffer_append_prefix(&buf, 32, ticket.age_add);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
- ret = _gnutls_buffer_append_prefix(&buf, 32, ticket.lifetime);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
+ /* append ticket_nonce */
+ ret = _gnutls_buffer_append_data_prefix(&buf, 8, ticket.nonce, ticket.nonce_size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
- ret = _gnutls_buffer_append_prefix(&buf, 32, ticket.age_add);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
+ /* append ticket */
+ ret = _gnutls_buffer_append_data_prefix(&buf, 16, ticket.ticket.data, ticket.ticket.size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
- /* append ticket_nonce */
- ret = _gnutls_buffer_append_data_prefix(&buf, 8, ticket.nonce, ticket.nonce_size);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
+ ret = _gnutls_buffer_append_prefix(&buf, 16, 0);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
- /* append ticket */
- ret = _gnutls_buffer_append_data_prefix(&buf, 16, ticket.ticket.data, ticket.ticket.size);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
+ _gnutls_free_datum(&ticket.ticket);
- ret = _gnutls_buffer_append_prefix(&buf, 16, 0);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
+ bufel = _gnutls_buffer_to_mbuffer(&buf);
- _gnutls_free_datum(&ticket.ticket);
+ ret = _gnutls_send_handshake2(session, bufel,
+ GNUTLS_HANDSHAKE_NEW_SESSION_TICKET, 1);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
- bufel = _gnutls_buffer_to_mbuffer(&buf);
+ session->internals.hsk_flags |= HSK_TLS13_TICKET_SENT;
+ }
}
- ret = _gnutls_send_handshake(session, bufel,
- GNUTLS_HANDSHAKE_NEW_SESSION_TICKET);
- if (ret > 0)
- session->internals.hsk_flags |= HSK_TLS13_TICKET_SENT;
+ ret = _gnutls_handshake_io_write_flush(session);
return ret;
cleanup:
_gnutls_free_datum(&ticket.ticket);
_mbuffer_xfree(&bufel);
+ _gnutls_buffer_clear(&buf);
return ret;
}
diff --git a/lib/tls13/session_ticket.h b/lib/tls13/session_ticket.h
index 073c28f1f2..d2f637c209 100644
--- a/lib/tls13/session_ticket.h
+++ b/lib/tls13/session_ticket.h
@@ -23,7 +23,7 @@
#define SESSION_TICKET_H
int _gnutls13_recv_session_ticket(gnutls_session_t session, gnutls_buffer_st *buf);
-int _gnutls13_send_session_ticket(gnutls_session_t session, unsigned again);
+int _gnutls13_send_session_ticket(gnutls_session_t session, unsigned nr, unsigned again);
int _gnutls13_unpack_session_ticket(gnutls_session_t session,
gnutls_datum_t *data,