diff options
author | Daiki Ueno <dueno@redhat.com> | 2018-10-19 17:52:48 +0200 |
---|---|---|
committer | Daiki Ueno <dueno@redhat.com> | 2018-11-12 14:08:45 +0100 |
commit | 79f2f1cf5b91491be5f0e3486c416594ec522b25 (patch) | |
tree | eec06e9a96e5c64449e3469c477fc1d332953d12 /lib/ext | |
parent | 8ada9c280c9044644dfad1f234e3da32f0df86a0 (diff) | |
download | gnutls-79f2f1cf5b91491be5f0e3486c416594ec522b25.tar.gz |
TLS 1.3: implement anti-replay measure using ClientHello recording
This implements ClientHello recording outlined in section 8.2 of RFC
8446.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
Diffstat (limited to 'lib/ext')
-rw-r--r-- | lib/ext/early_data.c | 3 | ||||
-rw-r--r-- | lib/ext/pre_shared_key.c | 27 |
2 files changed, 29 insertions, 1 deletions
diff --git a/lib/ext/early_data.c b/lib/ext/early_data.c index 729a528bd7..a58e473ae1 100644 --- a/lib/ext/early_data.c +++ b/lib/ext/early_data.c @@ -59,10 +59,13 @@ early_data_recv_params(gnutls_session_t session, return gnutls_assert_val(0); if (session->security_parameters.entity == GNUTLS_SERVER) { + /* The flag may be cleared by pre_shared_key + * extension, when replay is detected. */ if ((session->internals.flags & GNUTLS_ENABLE_EARLY_DATA) && /* Refuse early data when this is a second CH after HRR */ !(session->internals.hsk_flags & HSK_HRR_SENT)) session->internals.hsk_flags |= HSK_EARLY_DATA_ACCEPTED; + session->internals.hsk_flags |= HSK_EARLY_DATA_IN_FLIGHT; } else { if (_gnutls_ext_get_msg(session) == GNUTLS_EXT_FLAG_EE) diff --git a/lib/ext/pre_shared_key.c b/lib/ext/pre_shared_key.c index 7e4374042b..bc7fc8aa95 100644 --- a/lib/ext/pre_shared_key.c +++ b/lib/ext/pre_shared_key.c @@ -25,6 +25,7 @@ #include "auth/psk.h" #include "handshake.h" #include "secrets.h" +#include "tls13/anti_replay.h" #include "tls13/psk_ext_parser.h" #include "tls13/finished.h" #include "tls13/session_ticket.h" @@ -482,7 +483,9 @@ static int server_recv_params(gnutls_session_t session, struct psk_st psk; psk_auth_info_t info; tls13_ticket_st ticket_data; - uint32_t ticket_age; + /* These values should be set properly when session ticket is accepted. */ + uint32_t ticket_age = UINT32_MAX; + struct timespec ticket_creation_time = { 0, 0 }; bool resuming; ret = _gnutls13_psk_ext_parser_init(&psk_parser, data, len); @@ -526,6 +529,10 @@ static int server_recv_params(gnutls_session_t session, continue; } + memcpy(&ticket_creation_time, + &ticket_data.creation_time, + sizeof(struct timespec)); + tls13_ticket_deinit(&ticket_data); resuming = 1; @@ -612,6 +619,24 @@ static int server_recv_params(gnutls_session_t session, info->username[psk.identity.size] = 0; _gnutls_handshake_log("EXT[%p]: selected PSK identity: %s (%d)\n", session, info->username, psk_index); } else { + if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED) { + if (session->internals.anti_replay) { + ret = _gnutls_anti_replay_check(session, + ticket_age, + &ticket_creation_time, + &binder_recvd); + if (ret < 0) { + session->internals.hsk_flags &= ~HSK_EARLY_DATA_ACCEPTED; + _gnutls_handshake_log("EXT[%p]: replay detected; rejecting early data\n", + session); + } + } else { + _gnutls_handshake_log("EXT[%p]: anti-replay is not enabled; rejecting early data\n", + session); + session->internals.hsk_flags &= ~HSK_EARLY_DATA_ACCEPTED; + } + } + session->internals.resumed = RESUME_TRUE; _gnutls_handshake_log("EXT[%p]: selected resumption PSK identity (%d)\n", session, psk_index); } |