diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-11-02 15:19:10 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-02-19 15:29:36 +0100 |
commit | c0be323b29c0c31b7bc307f03df7db14816b0c48 (patch) | |
tree | 92469b39093ec6ab17f7f8c6c1227158e11f0e49 /lib/handshake-tls13.c | |
parent | 9ec15a01ee5982706adc92a938304eeb8a3de60a (diff) | |
download | gnutls-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.c | 37 |
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) |