From patchwork Fri Apr 22 04:29:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 2399 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director14.mail.ord1d.rsapps.net ([172.30.191.6]) by backend41.mail.ord1d.rsapps.net with LMTP id iK6nDV6+YmKWUwAAqwncew (envelope-from ) for ; Fri, 22 Apr 2022 10:40:30 -0400 Received: from proxy14.mail.ord1d.rsapps.net ([172.30.191.6]) by director14.mail.ord1d.rsapps.net with LMTP id KCr6Jl6+YmKaBAAAeJ7fFg (envelope-from ) for ; Fri, 22 Apr 2022 10:40:30 -0400 Received: from smtp24.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy14.mail.ord1d.rsapps.net with LMTPS id QGYwOGC+YmIdNgAAtEH5vw (envelope-from ) for ; Fri, 22 Apr 2022 10:40:32 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp24.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: 281725be-c24a-11ec-90bf-52540091a1c4-1-1 Received: from [216.105.38.7] ([216.105.38.7:39780] helo=lists.sourceforge.net) by smtp24.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 4D/3C-19047-E5EB2626; Fri, 22 Apr 2022 10:40:30 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.94.2) (envelope-from ) id 1nhuRR-0001Cy-4C; Fri, 22 Apr 2022 14:39:23 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nhuRQ-0001Cl-3b for openvpn-devel@lists.sourceforge.net; Fri, 22 Apr 2022 14:39:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=/VQtwGWh4QkursNA02ziLkA1i3eCCGbtzfX/xbkyavc=; b=cRKnDeTrmS5kEOrX2cLVwB77rB YBjOvNSRl/4b1YBdQyf0PH1VTZiEVpN+18NYq7r9OUp3/WaK7djXZ7kF7f6iQEMKwfZ6da1lpjeg+ Y3YaQs6T+yIn3CfZSvfpFrsREi4wlsyc4pAS+3ChZ9yC/+VOZ1Fjob6aPlsGAGYBJ6kg=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=/VQtwGWh4QkursNA02ziLkA1i3eCCGbtzfX/xbkyavc=; b=i2BqgjBmCVy3ku8dI39Qlkrmy3 MCDRl33sJI4SfR0WEU7riQXR6P5yn4e2WxXJ6FNXBcCqMIYgxSHiSfObUrozFgt0RK67cBb8eBeTT yC40eExG2vz42jZUnLSKlVvHOXoVAAvAecPjx6tO9i83GZ/z+4dRbAip0tzFBGphyxEA=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.94.2) id 1nhuRN-000668-M3 for openvpn-devel@lists.sourceforge.net; Fri, 22 Apr 2022 14:39:22 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.95 (FreeBSD)) (envelope-from ) id 1nhuIE-00096x-9K for openvpn-devel@lists.sourceforge.net; Fri, 22 Apr 2022 16:29:54 +0200 Received: (nullmailer pid 3805450 invoked by uid 10006); Fri, 22 Apr 2022 14:29:54 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Fri, 22 Apr 2022 16:29:48 +0200 Message-Id: <20220422142953.3805364-14-arne@rfc2549.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220422142953.3805364-1-arne@rfc2549.org> References: <20220422134038.3801239-1-arne@rfc2549.org> <20220422142953.3805364-1-arne@rfc2549.org> MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: We move to the S_START when we have finished the three-way handshake. After the three way handshake is done, the client will send the TLS Client Hello packet. Currently we consider the three way handshake only complete if all outgoing packet have been acked (which in this case is the one HARD_RESET_CLIENT or HARD_RESET_SERVER) and also all akcs for incoming [...] Content analysis details: (0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_NONE SPF: sender does not publish an SPF Record X-Headers-End: 1nhuRN-000668-M3 Subject: [Openvpn-devel] [PATCH 23/28] Optimise three-way handshake condition for S_PRE_START to S_START X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox We move to the S_START when we have finished the three-way handshake. After the three way handshake is done, the client will send the TLS Client Hello packet. Currently we consider the three way handshake only complete if all outgoing packet have been acked (which in this case is the one HARD_RESET_CLIENT or HARD_RESET_SERVER) and also all akcs for incoming packets are send out. The outgoing packet ack is important as it signal that the other side is really responding. The need to send out all ACKs before moving to the next state also breaks piggybacking the ACKs onto the next control packet. With this change both server and client will only send a P_CONTROL_V1 with the TLS Client Hello and the TLS Server Hello with piggybacked ack instead sending an P_ACK_V1 + P_CONTROL_V1, recuding the number of packets in a handshake by 2. This also allows the server to avoid resending P_CONTROL_HARD_RESET_V2 to complete the three-way handshake with HMAC. Only packets with an ACK contain the remote session id that we need for HMAC session id verification. The ACK_V1 packet that complets this three-way handshake can get lost. But the P_CONTROL_V1 with the piggybacked ACK will get retransmitted. This allows to put the burden of retransmission fully on the client. The S_GOT_KEY/S_SENT_KEY -> S_ACTIVE is similar. We do not need to wait for the ack packet to be sent to move the state forward. This has however no effect on actual packets since there are normally no outstanding ACKs here. Acked-By: Frank Lichtenheld --- src/openvpn/ssl.c | 15 +++++---------- tests/unit_tests/openvpn/test_pkt.c | 8 ++++---- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 5e1a23ccd..e3101c7fa 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1796,13 +1796,6 @@ flush_payload_buffer(struct key_state *ks) } } -/* true if no in/out acknowledgements pending */ -static bool -no_pending_reliable_packets(struct key_state *ks) -{ - return (reliable_empty(ks->send_reliable) && reliable_ack_empty(ks->rec_ack)); -} - /* * Move the active key to the lame duck key and reinitialize the * active key. @@ -2646,8 +2639,10 @@ tls_process_state(struct tls_multi *multi, goto error; } - /* Wait for Initial Handshake ACK */ - if (ks->state == S_PRE_START && no_pending_reliable_packets(ks)) + /* Check if the initial three-way Handshake is complete. + * This handshake can be considered to be complete when our own + * initial packet can been successfully acked. */ + if (ks->state == S_PRE_START && reliable_empty(ks->send_reliable)) { ks->state = S_START; state_change = true; @@ -2660,7 +2655,7 @@ tls_process_state(struct tls_multi *multi, /* Wait for ACK */ if (((ks->state == S_GOT_KEY && !session->opt->server) || (ks->state == S_SENT_KEY && session->opt->server)) - && no_pending_reliable_packets(ks)) + && reliable_empty(ks->send_reliable)) { session_move_active(multi, session, to_link_socket_info, ks); state_change = true; diff --git a/tests/unit_tests/openvpn/test_pkt.c b/tests/unit_tests/openvpn/test_pkt.c index 184b88383..d525def3c 100644 --- a/tests/unit_tests/openvpn/test_pkt.c +++ b/tests/unit_tests/openvpn/test_pkt.c @@ -531,7 +531,7 @@ test_generate_reset_packet_plain(void **ut_state) uint8_t header = 0 | (P_CONTROL_HARD_RESET_CLIENT_V2 << P_OPCODE_SHIFT); - struct buffer buf = tls_reset_standalone(&tas, &client_id, &server_id, header, 0, 0); + struct buffer buf = tls_reset_standalone(&tas.tls_wrap, &tas, &client_id, &server_id, header, false); verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); @@ -539,7 +539,7 @@ test_generate_reset_packet_plain(void **ut_state) /* Assure repeated generation of reset is deterministic/stateless*/ assert_memory_equal(state.peer_session_id.id, client_id.id, SID_SIZE); - struct buffer buf2 = tls_reset_standalone(&tas, &client_id, &server_id, header, 0, 0); + struct buffer buf2 = tls_reset_standalone(&tas.tls_wrap, &tas, &client_id, &server_id, header, false); assert_int_equal(BLEN(&buf), BLEN(&buf2)); assert_memory_equal(BPTR(&buf), BPTR(&buf2), BLEN(&buf)); free_buf(&buf2); @@ -566,7 +566,7 @@ test_generate_reset_packet_tls_auth(void **ut_state) now = 0x22446688; reset_packet_id_send(&tas_client.tls_wrap.opt.packet_id.send); - struct buffer buf = tls_reset_standalone(&tas_client, &client_id, &server_id, header, 0, 0); + struct buffer buf = tls_reset_standalone(&tas_client.tls_wrap, &tas_client, &client_id, &server_id, header, false); enum first_packet_verdict verdict = tls_pre_decrypt_lite(&tas_server, &state, &from, &buf); assert_int_equal(verdict, VERDICT_VALID_RESET_V2); @@ -575,7 +575,7 @@ test_generate_reset_packet_tls_auth(void **ut_state) /* Assure repeated generation of reset is deterministic/stateless*/ reset_packet_id_send(&tas_client.tls_wrap.opt.packet_id.send); - struct buffer buf2 = tls_reset_standalone(&tas_client, &client_id, &server_id, header, 0, 0); + struct buffer buf2 = tls_reset_standalone(&tas_client.tls_wrap, &tas_client, &client_id, &server_id, header,false); assert_int_equal(BLEN(&buf), BLEN(&buf2)); assert_memory_equal(BPTR(&buf), BPTR(&buf2), BLEN(&buf)); free_buf(&buf2);