diff mbox series

[2/4] tls: Improve renegotiation

Message ID 20221109174746.569046-2-andrew.zaborowski@intel.com (mailing list archive)
State Accepted, archived
Headers show
Series [1/4] tls: Allow ServerHello extensions when resuming session | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success

Commit Message

Andrew Zaborowski Nov. 9, 2022, 5:47 p.m. UTC
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.
---
 ell/tls.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/ell/tls.c b/ell/tls.c
index 5f3b717..14c8550 100644
--- a/ell/tls.c
+++ b/ell/tls.c
@@ -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: