diff options
-rw-r--r-- | lib/auth.c | 9 | ||||
-rw-r--r-- | lib/constate.c | 10 | ||||
-rw-r--r-- | lib/ext/session_ticket.c | 10 | ||||
-rw-r--r-- | lib/handshake-tls13.c | 6 | ||||
-rw-r--r-- | lib/session_pack.c | 1 | ||||
-rw-r--r-- | lib/tls13/session_ticket.c | 67 |
6 files changed, 77 insertions, 26 deletions
diff --git a/lib/auth.c b/lib/auth.c index 1ee2d72476..4bdedda38b 100644 --- a/lib/auth.c +++ b/lib/auth.c @@ -193,6 +193,9 @@ gnutls_credentials_get(gnutls_session_t session, * %GNUTLS_KX_RSA, %GNUTLS_KX_DHE_RSA), the same function are to be * used to access the authentication data. * + * Note that on resumed sessions, this function returns the schema + * used in the original session authentication. + * * Returns: The type of credentials for the current authentication * schema, a #gnutls_credentials_type_t type. **/ @@ -212,6 +215,9 @@ gnutls_credentials_type_t gnutls_auth_get_type(gnutls_session_t session) * The returned information is to be used to distinguish the function used * to access authentication data. * + * Note that on resumed sessions, this function returns the schema + * used in the original session authentication. + * * Returns: The type of credentials for the server authentication * schema, a #gnutls_credentials_type_t type. **/ @@ -229,6 +235,9 @@ gnutls_auth_server_get_type(gnutls_session_t session) * The returned information is to be used to distinguish the function used * to access authentication data. * + * Note that on resumed sessions, this function returns the schema + * used in the original session authentication. + * * Returns: The type of credentials for the client authentication * schema, a #gnutls_credentials_type_t type. **/ diff --git a/lib/constate.c b/lib/constate.c index ecfd53c494..cdf9ed6479 100644 --- a/lib/constate.c +++ b/lib/constate.c @@ -647,7 +647,9 @@ int _gnutls_epoch_set_keys(gnutls_session_t session, uint16_t epoch, hs_stage_t return 0; } - +/* This copies the session values which apply to subsequent/resumed + * sessions. Under TLS 1.3, these values are items which are not + * negotiated on the subsequent session. */ #define CPY_COMMON(tls13_sem) \ if (!tls13_sem) { \ dst->cs = src->cs; \ @@ -661,11 +663,11 @@ int _gnutls_epoch_set_keys(gnutls_session_t session, uint16_t epoch, hs_stage_t dst->prf = src->prf; \ dst->grp = src->grp; \ dst->pversion = src->pversion; \ + memcpy( dst->session_id, src->session_id, GNUTLS_MAX_SESSION_ID_SIZE); \ + dst->session_id_size = src->session_id_size; \ + dst->timestamp = src->timestamp; \ } \ - memcpy( dst->session_id, src->session_id, GNUTLS_MAX_SESSION_ID_SIZE); \ - dst->session_id_size = src->session_id_size; \ dst->cert_type = src->cert_type; \ - dst->timestamp = src->timestamp; \ dst->client_auth_type = src->client_auth_type; \ dst->server_auth_type = src->server_auth_type diff --git a/lib/ext/session_ticket.c b/lib/ext/session_ticket.c index 2bcc4cd984..2c91c9ec2d 100644 --- a/lib/ext/session_ticket.c +++ b/lib/ext/session_ticket.c @@ -594,9 +594,13 @@ int gnutls_session_ticket_enable_client(gnutls_session_t session) * @key: key to encrypt session parameters. * * Request that the server should attempt session resumption using - * SessionTicket. @key must be initialized with - * gnutls_session_ticket_key_generate(), and should be overwritten - * using gnutls_memset() before being released. + * session tickets, i.e., by delegating storage to the client. + * @key must be initialized using gnutls_session_ticket_key_generate(). + * To avoid leaking that key, use gnutls_memset() prior to + * releasing it. + * + * The default ticket expiration time can be overriden using + * gnutls_db_set_cache_expiration(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an * error code. diff --git a/lib/handshake-tls13.c b/lib/handshake-tls13.c index ef7862f9e2..effc260566 100644 --- a/lib/handshake-tls13.c +++ b/lib/handshake-tls13.c @@ -375,8 +375,12 @@ int _gnutls13_handshake_server(gnutls_session_t session) generate_ap_traffic_keys(session); STATE = STATE111; IMED_RET("generate app keys", ret, 0); + + if (session->internals.resumed != RESUME_FALSE) + _gnutls_set_resumed_parameters(session); /* fall through */ case STATE112: + ret = _gnutls13_send_session_ticket(session, AGAIN(STATE112)); STATE = STATE112; IMED_RET("send session ticket", ret, 0); @@ -393,8 +397,6 @@ int _gnutls13_handshake_server(gnutls_session_t session) SAVE_TRANSCRIPT; - if (session->internals.resumed != RESUME_FALSE) - _gnutls_set_resumed_parameters(session); return 0; } diff --git a/lib/session_pack.c b/lib/session_pack.c index be4cdafc2d..dd8e6f885a 100644 --- a/lib/session_pack.c +++ b/lib/session_pack.c @@ -1088,6 +1088,7 @@ unpack_security_parameters(gnutls_session_t session, gnutls_buffer_st * ps) session->internals.resumed_security_parameters. server_auth_type); + if (session->internals.resumed_security_parameters. max_record_recv_size == 0 || session->internals.resumed_security_parameters. diff --git a/lib/tls13/session_ticket.c b/lib/tls13/session_ticket.c index 4680a32d1a..25e067fc00 100644 --- a/lib/tls13/session_ticket.c +++ b/lib/tls13/session_ticket.c @@ -29,21 +29,31 @@ #include "ext/session_ticket.h" #include "auth/cert.h" #include "tls13/session_ticket.h" +#include "session_pack.h" static int -pack_ticket(tls13_ticket_t *ticket, gnutls_datum_t *state) +pack_ticket(gnutls_session_t session, tls13_ticket_t *ticket, gnutls_datum_t *packed) { uint8_t *p; + gnutls_datum_t state; + int ret; - state->size = 2 + 4 + 4 + + ret = _gnutls_session_pack(session, &state); + if (ret < 0) + return gnutls_assert_val(ret); + + packed->size = 2 + 4 + 4 + 1 + ticket->prf->output_size + - 1 + ticket->nonce_size; + 1 + ticket->nonce_size + 2 + state.size; - state->data = gnutls_malloc(state->size); - if (!state->data) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + packed->data = gnutls_malloc(packed->size); + if (!packed->data) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; + goto cleanup; + } - p = state->data; + p = packed->data; _gnutls_write_uint16(ticket->prf->id, p); p += 2; @@ -59,30 +69,41 @@ pack_ticket(tls13_ticket_t *ticket, gnutls_datum_t *state) p += 1; memcpy(p, ticket->nonce, ticket->nonce_size); + p += ticket->nonce_size; - return 0; + _gnutls_write_uint16(state.size, p); + p += 2; + + memcpy(p, state.data, state.size); + ret = 0; + + cleanup: + gnutls_free(state.data); + return ret; } static int -unpack_ticket(gnutls_datum_t *state, tls13_ticket_t *data) +unpack_ticket(gnutls_session_t session, gnutls_datum_t *packed, tls13_ticket_t *data) { uint32_t age_add, lifetime; uint8_t resumption_master_secret[MAX_HASH_SIZE]; size_t resumption_master_secret_size; uint8_t nonce[UINT8_MAX]; size_t nonce_size; + gnutls_datum_t state; gnutls_mac_algorithm_t kdf; const mac_entry_st *prf; uint8_t *p; ssize_t len; + int ret; - if (unlikely(state == NULL || data == NULL)) + if (unlikely(packed == NULL || data == NULL)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); memset(data, 0, sizeof(*data)); - p = state->data; - len = state->size; + p = packed->data; + len = packed->size; DECR_LEN(len, 2); kdf = _gnutls_read_uint16(p); @@ -125,6 +146,18 @@ unpack_ticket(gnutls_datum_t *state, tls13_ticket_t *data) DECR_LEN(len, nonce_size); memcpy(nonce, p, nonce_size); + p += nonce_size; + + DECR_LEN(len, 2); + state.size = _gnutls_read_uint16(p); + p += 2; + + DECR_LEN(len, state.size); + state.data = p; + + ret = _gnutls_session_unpack(session, &state); + if (ret < 0) + return gnutls_assert_val(ret); /* No errors - Now return all the data to the caller */ data->prf = prf; @@ -142,7 +175,7 @@ static int generate_session_ticket(gnutls_session_t session, tls13_ticket_t *ticket) { int ret; - gnutls_datum_t state = { NULL, 0 }; + gnutls_datum_t packed = { NULL, 0 }; tls13_ticket_t ticket_data; /* Generate a random 128-bit ticket nonce */ @@ -170,12 +203,12 @@ generate_session_ticket(gnutls_session_t session, tls13_ticket_t *ticket) session->key.proto.tls13.ap_rms, ticket->prf->output_size); - ret = pack_ticket(&ticket_data, &state); + ret = pack_ticket(session, &ticket_data, &packed); if (ret < 0) return gnutls_assert_val(ret); - ret = _gnutls_encrypt_session_ticket(session, &state, &ticket->ticket); - _gnutls_free_datum(&state); + ret = _gnutls_encrypt_session_ticket(session, &packed, &ticket->ticket); + _gnutls_free_datum(&packed); if (ret < 0) return gnutls_assert_val(ret); @@ -343,7 +376,7 @@ int _gnutls13_unpack_session_ticket(gnutls_session_t session, return gnutls_assert_val(ret); /* Return ticket parameters */ - ret = unpack_ticket(&decrypted, ticket_data); + ret = unpack_ticket(session, &decrypted, ticket_data); _gnutls_free_datum(&decrypted); if (ret < 0) { return ret; |