diff options
-rw-r--r-- | lib/handshake-tls13.c | 8 | ||||
-rw-r--r-- | lib/handshake.c | 31 | ||||
-rw-r--r-- | lib/handshake.h | 5 | ||||
-rw-r--r-- | tests/tls13/key_update.c | 53 |
4 files changed, 78 insertions, 19 deletions
diff --git a/lib/handshake-tls13.c b/lib/handshake-tls13.c index 427392b6f3..ef7862f9e2 100644 --- a/lib/handshake-tls13.c +++ b/lib/handshake-tls13.c @@ -430,6 +430,10 @@ _gnutls13_recv_async_handshake(gnutls_session_t session, gnutls_buffer_st *buf) if (ret < 0) return gnutls_assert_val(ret); + ret = _gnutls_call_hook_func(session, type, GNUTLS_HOOK_PRE, 1, buf->data, buf->length); + if (ret < 0) + return gnutls_assert_val(ret); + switch(type) { case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST: if (!(session->security_parameters.entity == GNUTLS_CLIENT) || @@ -474,6 +478,10 @@ _gnutls13_recv_async_handshake(gnutls_session_t session, gnutls_buffer_st *buf) return GNUTLS_E_UNEXPECTED_PACKET; } + ret = _gnutls_call_hook_func(session, type, GNUTLS_HOOK_POST, 1, buf->data, buf->length); + if (ret < 0) + return gnutls_assert_val(ret); + return 0; } diff --git a/lib/handshake.c b/lib/handshake.c index a023ab2ad4..c12ecefa8c 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -800,7 +800,7 @@ int _gnutls_send_finished(gnutls_session_t session, int again) if (again == 0) { bufel = - _gnutls_handshake_alloc(session, + _gnutls_handshake_alloc(session, MAX_VERIFY_DATA_SIZE); if (bufel == NULL) { gnutls_assert(); @@ -1116,11 +1116,10 @@ _gnutls_send_empty_handshake(gnutls_session_t session, return _gnutls_send_handshake(session, bufel, type); } -inline - static int call_hook_func(gnutls_session_t session, - gnutls_handshake_description_t type, - int post, unsigned incoming, - const uint8_t *data, unsigned data_size) +int _gnutls_call_hook_func(gnutls_session_t session, + gnutls_handshake_description_t type, + int post, unsigned incoming, + const uint8_t *data, unsigned data_size) { gnutls_datum_t msg = {(void*)data, data_size}; @@ -1214,8 +1213,8 @@ _gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel, return ret; } - ret = call_hook_func(session, type, GNUTLS_HOOK_PRE, 0, - _mbuffer_get_udata_ptr(bufel), _mbuffer_get_udata_size(bufel)); + ret = _gnutls_call_hook_func(session, type, GNUTLS_HOOK_PRE, 0, + _mbuffer_get_udata_ptr(bufel), _mbuffer_get_udata_size(bufel)); if (ret < 0) { gnutls_assert(); _mbuffer_xfree(&bufel); @@ -1231,8 +1230,8 @@ _gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel, return ret; } - ret = call_hook_func(session, type, GNUTLS_HOOK_POST, 0, - _mbuffer_get_udata_ptr(bufel), _mbuffer_get_udata_size(bufel)); + ret = _gnutls_call_hook_func(session, type, GNUTLS_HOOK_POST, 0, + _mbuffer_get_udata_ptr(bufel), _mbuffer_get_udata_size(bufel)); if (ret < 0) { gnutls_assert(); return ret; @@ -1441,7 +1440,7 @@ _gnutls_recv_handshake(gnutls_session_t session, } session->internals.last_handshake_in = hsk.htype; - ret = call_hook_func(session, hsk.htype, GNUTLS_HOOK_PRE, 1, hsk.data.data, hsk.data.length); + ret = _gnutls_call_hook_func(session, hsk.htype, GNUTLS_HOOK_PRE, 1, hsk.data.data, hsk.data.length); if (ret < 0) { gnutls_assert(); goto cleanup; @@ -1567,7 +1566,7 @@ _gnutls_recv_handshake(gnutls_session_t session, goto cleanup; } - ret2 = call_hook_func(session, hsk.htype, GNUTLS_HOOK_POST, 1, hsk.data.data, hsk.data.length); + ret2 = _gnutls_call_hook_func(session, hsk.htype, GNUTLS_HOOK_POST, 1, hsk.data.data, hsk.data.length); if (ret2 < 0) { ret = ret2; gnutls_assert(); @@ -3011,8 +3010,8 @@ ssize_t _gnutls_send_change_cipher_spec(gnutls_session_t session, int again) session->internals.dtls.hsk_write_seq++; } - ret = call_hook_func(session, GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC, GNUTLS_HOOK_PRE, 0, - data, 1); + ret = _gnutls_call_hook_func(session, GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC, GNUTLS_HOOK_PRE, 0, + data, 1); if (ret < 0) { _mbuffer_xfree(&bufel); return gnutls_assert_val(ret); @@ -3027,8 +3026,8 @@ ssize_t _gnutls_send_change_cipher_spec(gnutls_session_t session, int again) return gnutls_assert_val(ret); } - ret = call_hook_func(session, GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC, GNUTLS_HOOK_POST, 0, - data, 1); + ret = _gnutls_call_hook_func(session, GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC, GNUTLS_HOOK_POST, 0, + data, 1); if (ret < 0) { return gnutls_assert_val(ret); } diff --git a/lib/handshake.h b/lib/handshake.h index bdd9efa76d..465ee03b80 100644 --- a/lib/handshake.h +++ b/lib/handshake.h @@ -142,6 +142,11 @@ int _gnutls_check_if_cert_hash_is_same(gnutls_session_t session, gnutls_certific #define EXPORTER_LABEL "exp master" #define RES_LABEL "res master" +int _gnutls_call_hook_func(gnutls_session_t session, + gnutls_handshake_description_t type, + int post, unsigned incoming, + const uint8_t *data, unsigned data_size); + int _gnutls_run_verify_callback(gnutls_session_t session, unsigned int side); int _gnutls_recv_finished(gnutls_session_t session); int _gnutls_send_finished(gnutls_session_t session, int again); diff --git a/tests/tls13/key_update.c b/tests/tls13/key_update.c index ac5f5cc1a5..bed8a682b4 100644 --- a/tests/tls13/key_update.c +++ b/tests/tls13/key_update.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Red Hat, Inc. + * Copyright (C) 2017-2018 Red Hat, Inc. * * Author: Nikos Mavrogiannopoulos * @@ -46,6 +46,26 @@ static void tls_log_func(int level, const char *str) #define MAX_BUF 1024 #define MSG "Hello TLS, and hi and how are you and more data here... and more... and even more and even more more data..." +static unsigned key_update_msg_inc = 0; +static unsigned key_update_msg_out = 0; + +static int hsk_callback(gnutls_session_t session, unsigned int htype, + unsigned post, unsigned int incoming, const gnutls_datum_t *msg) +{ + assert(post == GNUTLS_HOOK_PRE); + + assert(msg->size == 1); + + if (htype == GNUTLS_HANDSHAKE_KEY_UPDATE) { + if (incoming) + key_update_msg_inc++; + else + key_update_msg_out++; + } + + return 0; +} + static void run(const char *name, unsigned test) { /* Server stuff. */ @@ -105,6 +125,7 @@ static void run(const char *name, unsigned test) gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); + HANDSHAKE(client, server); if (debug) success("Handshake established\n"); @@ -169,6 +190,8 @@ static void run(const char *name, unsigned test) TRANSFER(client, server, MSG, strlen(MSG), buffer, MAX_BUF); TRANSFER(server, client, MSG, strlen(MSG), buffer, MAX_BUF); EMPTY_BUF(server, client, buffer, MAX_BUF); + + sec_sleep(2); break; case 5: success("%s: client cork\n", name); @@ -199,11 +222,34 @@ static void run(const char *name, unsigned test) fail("cannot send: %s\n", gnutls_strerror(ret)); EMPTY_BUF(server, client, buffer, MAX_BUF); + + sec_sleep(2); + break; + case 6: + key_update_msg_inc = 0; + key_update_msg_out = 0; + + success("%s: callbacks are called\n", name); + + gnutls_handshake_set_hook_function(client, -1, GNUTLS_HOOK_PRE, hsk_callback); + gnutls_handshake_set_hook_function(server, -1, GNUTLS_HOOK_PRE, hsk_callback); + + do { + ret = gnutls_session_key_update(client, GNUTLS_KU_PEER); + } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); + if (ret < 0) + fail("error in key update: %s\n", gnutls_strerror(ret)); + + /* server receives the client key update and sends data */ + TRANSFER(client, server, MSG, strlen(MSG), buffer, MAX_BUF); + TRANSFER(server, client, MSG, strlen(MSG), buffer, MAX_BUF); + EMPTY_BUF(server, client, buffer, MAX_BUF); + + assert(key_update_msg_inc == 2); + assert(key_update_msg_out == 2); break; } - if (debug) - fputs("\n", stdout); gnutls_bye(client, GNUTLS_SHUT_WR); gnutls_bye(server, GNUTLS_SHUT_WR); @@ -225,5 +271,6 @@ void doit(void) run("single", 3); run("single", 4); run("single", 5); + run("single", 6); run("all", 0); /* all one after each other */ } |