summaryrefslogtreecommitdiff
path: root/lib/handshake-tls13.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-11-02 15:19:10 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-02-19 15:29:36 +0100
commitc0be323b29c0c31b7bc307f03df7db14816b0c48 (patch)
tree92469b39093ec6ab17f7f8c6c1227158e11f0e49 /lib/handshake-tls13.c
parent9ec15a01ee5982706adc92a938304eeb8a3de60a (diff)
downloadgnutls-c0be323b29c0c31b7bc307f03df7db14816b0c48.tar.gz
handshake: added support for post-handshake authentication
That is: * introduced a gnutls_init() flag for clients to enable post-handshake authentication * introduced gnutls_reauth() function, to be called by servers to request authentication, and by clients to perform authentication Resolves #562 Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/handshake-tls13.c')
-rw-r--r--lib/handshake-tls13.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/handshake-tls13.c b/lib/handshake-tls13.c
index d7e6d168d1..03b08285da 100644
--- a/lib/handshake-tls13.c
+++ b/lib/handshake-tls13.c
@@ -59,6 +59,16 @@
static int generate_hs_traffic_keys(gnutls_session_t session);
static int generate_ap_traffic_keys(gnutls_session_t session);
+#define SAVE_TRANSCRIPT \
+ if (session->internals.flags & GNUTLS_POST_HANDSHAKE_AUTH) { \
+ /* If post-handshake auth is in use we need a copy of the original \
+ * handshake transcript */ \
+ memcpy( &session->internals.post_handshake_hash_buffer, \
+ &session->internals.handshake_hash_buffer, \
+ sizeof(session->internals.handshake_hash_buffer)); \
+ _gnutls_buffer_init(&session->internals.handshake_hash_buffer); \
+ }
+
/*
* _gnutls13_handshake_client
* This function performs the client side of the handshake of the TLS/SSL protocol.
@@ -136,6 +146,8 @@ int _gnutls13_handshake_client(gnutls_session_t session)
session->internals.recv_state = RECV_STATE_0;
session->internals.initial_negotiation_completed = 1;
+ SAVE_TRANSCRIPT;
+
return 0;
}
@@ -311,9 +323,16 @@ int _gnutls13_handshake_server(gnutls_session_t session)
session->internals.recv_state = RECV_STATE_0;
session->internals.initial_negotiation_completed = 1;
+ SAVE_TRANSCRIPT;
+
return 0;
}
+/* Processes handshake messages received asynchronously after initial handshake.
+ *
+ * It is called once per message, with a read-only buffer in @buf,
+ * and should return success, or a fatal error code.
+ */
int
_gnutls13_recv_async_handshake(gnutls_session_t session, gnutls_buffer_st *buf)
{
@@ -341,6 +360,24 @@ _gnutls13_recv_async_handshake(gnutls_session_t session, gnutls_buffer_st *buf)
return gnutls_assert_val(ret);
switch(type) {
+ case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
+ if (!(session->security_parameters.entity == GNUTLS_CLIENT) ||
+ !(session->internals.flags & GNUTLS_POST_HANDSHAKE_AUTH)) {
+ return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
+ }
+
+ _gnutls_buffer_reset(&session->internals.reauth_buffer);
+
+ /* include the handshake headers in reauth buffer */
+ ret = _gnutls_buffer_append_data(&session->internals.reauth_buffer,
+ buf->data-4, buf->length+4);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ /* Application is expected to handle re-authentication
+ * explicitly. */
+ return GNUTLS_E_REAUTH_REQUEST;
+
case GNUTLS_HANDSHAKE_KEY_UPDATE:
ret = _gnutls13_recv_key_update(session, buf);
if (ret < 0)