From patchwork Wed Apr 27 12:34:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 2420 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.31.255.6]) by backend41.mail.ord1d.rsapps.net with LMTP id V4MkBUvFaWKdCwAAqwncew (envelope-from ) for ; Wed, 27 Apr 2022 18:35:55 -0400 Received: from proxy1.mail.iad3b.rsapps.net ([172.31.255.6]) by director9.mail.ord1d.rsapps.net with LMTP id IJh7IUvFaWKhRQAAalYnBA (envelope-from ) for ; Wed, 27 Apr 2022 18:35:55 -0400 Received: from smtp27.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy1.mail.iad3b.rsapps.net with LMTPS id aoCJGkvFaWKZVgAALM5PBw (envelope-from ) for ; Wed, 27 Apr 2022 18:35:55 -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: smtp27.gate.iad3b.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: 660107b2-c67a-11ec-b3cc-5254006b1ac1-1-1 Received: from [216.105.38.7] ([216.105.38.7:36618] helo=lists.sourceforge.net) by smtp27.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 10/5F-25932-A45C9626; Wed, 27 Apr 2022 18:35:54 -0400 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.94.2) (envelope-from ) id 1njqF2-0001dy-IB; Wed, 27 Apr 2022 22:34:37 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1njqF1-0001ds-Ig for openvpn-devel@lists.sourceforge.net; Wed, 27 Apr 2022 22:34:36 +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=hvWUruAThx1Hf2t21IoMm2XZCtgCbGRuYL7Rdf2jhD8=; b=Fxcej6+R9bZxVCrA2fA+emMtk6 oHvN9FnjElsG6xLbG6eBEntqzAxoE2eqsE5yhZ9wLRBkVds1BTsbomr4u4gystT8VALOmPMzk6CzN 81NKvkVq/urTTlLp+VQ6lLkEbTsFWf73sA0jCkPd31hm43u/YqjoRD3TaccS1TV7Xhrc=; 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=hvWUruAThx1Hf2t21IoMm2XZCtgCbGRuYL7Rdf2jhD8=; b=BUg+jBhuLnzWkPW8fH/eXmEorI X766AIlPl9DNg1SAVlkxtCJHA+K1K9DrZuH7PjfKTVNiBJMMq0cE2WA936+zckxYylLXz2BUAE8Hk +o4SeylQHQgWMj+PCgSklJnE1qoEudctZFFk9WlgARlHUR/H3wAaipBPrUgI/uFEGjis=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.94.2) id 1njqEx-00C7sk-Op for openvpn-devel@lists.sourceforge.net; Wed, 27 Apr 2022 22:34:36 +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 1njqEm-000FA4-0S for openvpn-devel@lists.sourceforge.net; Thu, 28 Apr 2022 00:34:20 +0200 Received: (nullmailer pid 241950 invoked by uid 10006); Wed, 27 Apr 2022 22:34:19 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Thu, 28 Apr 2022 00:34:18 +0200 Message-Id: <20220427223419.241904-1-arne@rfc2549.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220422134038.3801239-1-arne@rfc2549.org> References: <20220422134038.3801239-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: This implement creating a reset packet without needing to setup a full control session. Patch v2: fix unit test not working without further commits Signed-off-by: Arne Schwabe --- src/openvpn/packet_id.h | 15 ++++ src/openvpn/ssl.h | 6 -- src/openvpn/ssl_pkt.c | 32 +++++++ src/openvpn/ssl_pkt.h | 19 +++++ tests/unit_tests/openv [...] 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.0 SPF_NONE SPF: sender does not publish an SPF Record 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different X-Headers-End: 1njqEx-00C7sk-Op Subject: [Openvpn-devel] [PATCH v2] Implement constructing a control channel reset client as standalone fucntion 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 This implement creating a reset packet without needing to setup a full control session. Patch v2: fix unit test not working without further commits Signed-off-by: Arne Schwabe --- src/openvpn/packet_id.h | 15 ++++ src/openvpn/ssl.h | 6 -- src/openvpn/ssl_pkt.c | 32 +++++++ src/openvpn/ssl_pkt.h | 19 +++++ tests/unit_tests/openvpn/test_pkt.c | 127 +++++++++++++++++++++++----- 5 files changed, 172 insertions(+), 27 deletions(-) diff --git a/src/openvpn/packet_id.h b/src/openvpn/packet_id.h index 410071e26..e5ffd485c 100644 --- a/src/openvpn/packet_id.h +++ b/src/openvpn/packet_id.h @@ -289,6 +289,21 @@ packet_id_persist_save_obj(struct packet_id_persist *p, const struct packet_id * } } +/** + * Reset the current send packet id to its initial state. + * Use very carefully only as (e.g. in the standalone reset packet context) + * to avoid sending more than one packet with the same packet id (that is not + * also a resend like the reset packet) + * + * @param p the packet structure to modify + */ +static inline void +reset_packet_id_send(struct packet_id_send *p) +{ + p->time = 0; + p->id = 0; +} + const char *packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc); static inline int diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index ddf70422a..e925a16ea 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -53,12 +53,6 @@ */ #define CONTROL_SEND_ACK_MAX 4 -/* - * Define number of buffers for send and receive in the reliability layer. - */ -#define TLS_RELIABLE_N_SEND_BUFFERS 4 /* also window size for reliability layer */ -#define TLS_RELIABLE_N_REC_BUFFERS 8 - /* * Various timeouts */ diff --git a/src/openvpn/ssl_pkt.c b/src/openvpn/ssl_pkt.c index 7233871b1..a93027505 100644 --- a/src/openvpn/ssl_pkt.c +++ b/src/openvpn/ssl_pkt.c @@ -398,3 +398,35 @@ error: gc_free(&gc); return VERDICT_INVALID; } + +struct buffer +tls_reset_standalone(struct tls_auth_standalone *tas, + struct session_id *own_sid, + struct session_id *remote_sid, + uint8_t header) +{ + struct buffer buf = alloc_buf(tas->frame.buf.payload_size); + ASSERT(buf_init(&buf, tas->frame.buf.headroom)); + + /* Reliable ACK structure */ + /* Length of the ACK structure - 1 ACK */ + buf_write_u8(&buf, 1); + + /* ACKed packet - first packet's id is always 0 */ + buf_write_u32(&buf, 0); + + /* Remote session id */ + buf_write(&buf, remote_sid->id, SID_SIZE); + + /* Packet ID of our own packet: Our reset packet is always using + * packet id 0 since it is the first packet */ + packet_id_type net_pid = htonpid(0); + + ASSERT(buf_write(&buf, &net_pid, sizeof(net_pid))); + + /* Add tls-auth/tls-crypt wrapping, this might replace buf */ + tls_wrap_control(&tas->tls_wrap, header, &buf, own_sid); + + return buf; +} + diff --git a/src/openvpn/ssl_pkt.h b/src/openvpn/ssl_pkt.h index b7a8d9c35..dd9361407 100644 --- a/src/openvpn/ssl_pkt.h +++ b/src/openvpn/ssl_pkt.h @@ -60,6 +60,12 @@ #define P_FIRST_OPCODE 3 #define P_LAST_OPCODE 10 +/* + * Define number of buffers for send and receive in the reliability layer. + */ +#define TLS_RELIABLE_N_SEND_BUFFERS 4 /* also window size for reliability layer */ +#define TLS_RELIABLE_N_REC_BUFFERS 8 + /* * Used in --mode server mode to check tls-auth signature on initial * packets received from new clients. @@ -157,6 +163,19 @@ read_control_auth(struct buffer *buf, const struct link_socket_actual *from, const struct tls_options *opt); + +/** + * This function creates a reset packet using the information + * from the tls pre decrypt state. + * + * The returned buf need to be free with \c free_buf + */ +struct buffer +tls_reset_standalone(struct tls_auth_standalone *tas, + struct session_id *own_sid, + struct session_id *remote_sid, + uint8_t header); + static inline const char * packet_opcode_name(int op) { diff --git a/tests/unit_tests/openvpn/test_pkt.c b/tests/unit_tests/openvpn/test_pkt.c index 022e15d3e..77338cd3a 100644 --- a/tests/unit_tests/openvpn/test_pkt.c +++ b/tests/unit_tests/openvpn/test_pkt.c @@ -87,25 +87,25 @@ const char static_key[] = "\n" "\n"; const uint8_t client_reset_v2_none[] = - { 0x38, 0x68, 0x91, 0x92, 0x3f, 0xa3, 0x10, 0x34, - 0x37, 0x00, 0x00, 0x00, 0x00, 0x00 }; +{ 0x38, 0x68, 0x91, 0x92, 0x3f, 0xa3, 0x10, 0x34, + 0x37, 0x00, 0x00, 0x00, 0x00, 0x00 }; const uint8_t client_reset_v2_tls_auth[] = - { 0x38, 0xde, 0x69, 0x4c, 0x5c, 0x7b, 0xfb, 0xa2, - 0x74, 0x93, 0x53, 0x7c, 0x1d, 0xed, 0x4e, 0x78, - 0x15, 0x29, 0xae, 0x7c, 0xfe, 0x4b, 0x8c, 0x6d, - 0x6b, 0x2b, 0x51, 0xf0, 0x5a, 0x00, 0x00, 0x00, - 0x01, 0x61, 0xd3, 0xbf, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00}; +{ 0x38, 0xde, 0x69, 0x4c, 0x5c, 0x7b, 0xfb, 0xa2, + 0x74, 0x93, 0x53, 0x7c, 0x1d, 0xed, 0x4e, 0x78, + 0x15, 0x29, 0xae, 0x7c, 0xfe, 0x4b, 0x8c, 0x6d, + 0x6b, 0x2b, 0x51, 0xf0, 0x5a, 0x00, 0x00, 0x00, + 0x01, 0x61, 0xd3, 0xbf, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00}; const uint8_t client_reset_v2_tls_crypt[] = - {0x38, 0xf4, 0x19, 0xcb, 0x12, 0xd1, 0xf9, 0xe4, - 0x8f, 0x00, 0x00, 0x00, 0x01, 0x61, 0xd3, 0xf8, - 0xe1, 0x33, 0x02, 0x06, 0xf5, 0x68, 0x02, 0xbe, - 0x44, 0xfb, 0xed, 0x90, 0x50, 0x64, 0xe3, 0xdb, - 0x43, 0x41, 0x6b, 0xec, 0x5e, 0x52, 0x67, 0x19, - 0x46, 0x2b, 0x7e, 0xb9, 0x0c, 0x96, 0xde, 0xfc, - 0x9b, 0x05, 0xc4, 0x48, 0x79, 0xf7}; +{0x38, 0xf4, 0x19, 0xcb, 0x12, 0xd1, 0xf9, 0xe4, + 0x8f, 0x00, 0x00, 0x00, 0x01, 0x61, 0xd3, 0xf8, + 0xe1, 0x33, 0x02, 0x06, 0xf5, 0x68, 0x02, 0xbe, + 0x44, 0xfb, 0xed, 0x90, 0x50, 0x64, 0xe3, 0xdb, + 0x43, 0x41, 0x6b, 0xec, 0x5e, 0x52, 0x67, 0x19, + 0x46, 0x2b, 0x7e, 0xb9, 0x0c, 0x96, 0xde, 0xfc, + 0x9b, 0x05, 0xc4, 0x48, 0x79, 0xf7}; /* Valid tls-auth client CONTROL_V1 packet with random server id */ const uint8_t client_ack_tls_auth_randomid[] = { @@ -148,15 +148,19 @@ const uint8_t client_ack_tls_auth_randomid[] = { 0xdb, 0x56, 0xf6, 0x40, 0xd1, 0xed, 0xdb, 0x91, 0x81, 0xd6, 0xef, 0x83, 0x86, 0x8a, 0xb2, 0x3d, 0x88, 0x92, 0x3f, 0xd8, 0x51, 0x9c, 0xd6, 0x26, - 0x56, 0x33, 0x6b}; + 0x56, 0x33, 0x6b +}; -struct tls_auth_standalone init_tas_auth(int key_direction) +struct tls_auth_standalone +init_tas_auth(int key_direction) { struct tls_auth_standalone tas = { 0 }; + struct frame frame = { {.headroom = 200, .payload_size = 1400}, 0}; + tas.frame = frame; tas.tls_wrap.mode = TLS_WRAP_AUTH; /* we ignore packet ids on for the first packet check */ - tas.tls_wrap.opt.flags |= CO_IGNORE_PACKET_ID; + tas.tls_wrap.opt.flags |= (CO_IGNORE_PACKET_ID|CO_PACKET_ID_LONG_FORM); struct key_type tls_crypt_kt; init_key_type(&tls_crypt_kt, "none", "SHA1", true, false); @@ -167,11 +171,12 @@ struct tls_auth_standalone init_tas_auth(int key_direction) return tas; } -struct tls_auth_standalone init_tas_crypt(bool server) +struct tls_auth_standalone +init_tas_crypt(bool server) { struct tls_auth_standalone tas = { 0 }; tas.tls_wrap.mode = TLS_WRAP_CRYPT; - tas.tls_wrap.opt.flags |= CO_IGNORE_PACKET_ID; + tas.tls_wrap.opt.flags |= (CO_IGNORE_PACKET_ID|CO_PACKET_ID_LONG_FORM); tls_crypt_init_key(&tas.tls_wrap.opt.key_ctx_bi, static_key, true, server); @@ -209,7 +214,7 @@ test_tls_decrypt_lite_crypt(void **ut_state) free_tls_pre_decrypt_state(&state); /* flip a byte in various places */ - for (int i=0;i