diff options
author | Andrew Zaborowski <andrew.zaborowski@intel.com> | 2022-11-09 18:47:44 +0100 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2022-11-09 14:24:22 -0600 |
commit | 6f81345ed9e4bd1fe0dea7edc90c395674f32f5d (patch) | |
tree | 7a842d1f0a99e99e3fa97c18ff4469f21fd28d1e | |
parent | 3bf4376f437f81c3c4a693bbea966248085738ce (diff) |
tls: Improve renegotiation
On client, allow renegotiation triggered by the server. Make sure to
reset tls->peer_authenticated before a new handshake. Avoid calling the
ready callback multiple times, only call it after initial handshake.
While RFC 5746 makes the case for TLS APIs to inform the application
layer of renegotiations, some ell users don't consider the possiblity of
the ready callback happening more than once in a session and the name
implies that the TLS tunnel wasn't ready before the call.
-rw-r--r-- | ell/tls.c | 19 |
1 files changed, 16 insertions, 3 deletions
@@ -198,6 +198,7 @@ static void tls_reset_handshake(struct l_tls *tls) tls->peer_cert = NULL; tls->peer_pubkey = NULL; tls->peer_pubkey_size = 0; + tls->peer_authenticated = false; tls->negotiated_curve = NULL; tls->negotiated_ff_group = NULL; @@ -2898,6 +2899,7 @@ static void tls_finished(struct l_tls *tls) uint64_t peer_cert_expiry; bool resuming = tls->session_id_size && !tls->session_id_new; bool session_update = false; + bool renegotiation = tls->ready; if (tls->peer_authenticated && !resuming) { peer_cert_identity = tls_get_peer_identity_str(tls->peer_cert); @@ -2998,9 +3000,11 @@ static void tls_finished(struct l_tls *tls) return; } - tls->in_callback = true; - tls->ready_handle(peer_identity, tls->user_data); - tls->in_callback = false; + if (!renegotiation) { + tls->in_callback = true; + tls->ready_handle(peer_identity, tls->user_data); + tls->in_callback = false; + } tls_cleanup_handshake(tls); } @@ -3033,7 +3037,16 @@ static void tls_handle_handshake(struct l_tls *tls, int type, * and "MAY be ignored by the client if it does not wish to * renegotiate a session". */ + if (tls->state != TLS_HANDSHAKE_DONE) { + TLS_DEBUG("Message invalid in state %s", + tls_handshake_state_to_str(tls->state)); + break; + } + + if (!tls_send_client_hello(tls)) + break; + TLS_SET_STATE(TLS_HANDSHAKE_WAIT_HELLO); break; case TLS_CLIENT_HELLO: |