From patchwork Fri Apr 22 03:40:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 2406 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.31.255.6]) by backend41.mail.ord1d.rsapps.net with LMTP id YJG+CS3FYmKGEQAAqwncew (envelope-from ) for ; Fri, 22 Apr 2022 11:09:33 -0400 Received: from proxy15.mail.iad3b.rsapps.net ([172.31.255.6]) by director7.mail.ord1d.rsapps.net with LMTP id 0LLUDC3FYmJVaQAAovjBpQ (envelope-from ) for ; Fri, 22 Apr 2022 11:09:33 -0400 Received: from smtp24.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy15.mail.iad3b.rsapps.net with LMTPS id oO+TBC3FYmK3WgAAhyf7VQ (envelope-from ) for ; Fri, 22 Apr 2022 11:09:33 -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.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: 36543938-c24e-11ec-9973-525400892b35-1-1 Received: from [216.105.38.7] ([216.105.38.7:43442] helo=lists.sourceforge.net) by smtp24.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 31/E1-25362-C25C2626; Fri, 22 Apr 2022 11:09:32 -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 1nhutQ-0002Nj-Am; Fri, 22 Apr 2022 15:08:18 +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 1nhutO-0002Nd-SS for openvpn-devel@lists.sourceforge.net; Fri, 22 Apr 2022 15:08:17 +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=Pe5qlu/qupwz+bfdiJm+E0fjrxXINzHVn7Pa561oDnI=; b=DB2vRoRXCZVEljyd8UMksrinze DBE8uZjkreCbInGs6hU0AtJ6KW7dvZlSxnxYCnlXzGaTgoxyoU9J8Y4YGxR7zA1TGXiN4Lpks2lAt IY09bVCjqkZBNy8sXFdBX5ErLsE/qOKE9L/374HZs8MkToCTIXMF55eaym1QZ7ZA1q7Q=; 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=Pe5qlu/qupwz+bfdiJm+E0fjrxXINzHVn7Pa561oDnI=; b=cb2BJrTWfrAWI0DeLXyzCfKYHC 78RMMmY+laR7gRru+hYlCt9F4ZpdG3GdoqbJiGo5LBs+gQfWsxs4Q7EueySbbpdFveJR2HB23DR48 ipLxm0s91WFXpgjvZllieKWEdeS8zFo9CHqVfKHK55FkJqR27v0tSVP7m3aeKUkYBuO8=; 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 1nhutL-0007Ta-PD for openvpn-devel@lists.sourceforge.net; Fri, 22 Apr 2022 15:08:17 +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 1nhtWY-0008sY-Te for openvpn-devel@lists.sourceforge.net; Fri, 22 Apr 2022 15:40:38 +0200 Received: (nullmailer pid 3801306 invoked by uid 10006); Fri, 22 Apr 2022 13:40:38 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Fri, 22 Apr 2022 15:40:36 +0200 Message-Id: <20220422134038.3801239-8-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-1.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 tests currently the existing functionality of test_tls_decrypt_lite to check if a reset packet is valid or not. Signed-off-by: Arne Schwabe --- tests/unit_tests/openvpn/Makefile.am | 24 +- tests/unit_tests/openvpn/test_pkt.c | 347 +++++++++++++++++++++++++++ 2 files changed, 370 insertions(+) [...] Content analysis details: (0.3 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: 1nhutL-0007Ta-PD Subject: [Openvpn-devel] [PATCH 07/28] Add unit tests for test_tls_decrypt_lite 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 tests currently the existing functionality of test_tls_decrypt_lite to check if a reset packet is valid or not. Signed-off-by: Arne Schwabe Acked-by: Gert Doering --- tests/unit_tests/openvpn/Makefile.am | 24 +- tests/unit_tests/openvpn/test_pkt.c | 347 +++++++++++++++++++++++++++ 2 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 tests/unit_tests/openvpn/test_pkt.c diff --git a/tests/unit_tests/openvpn/Makefile.am b/tests/unit_tests/openvpn/Makefile.am index 4141b53f8..63b53a6ac 100644 --- a/tests/unit_tests/openvpn/Makefile.am +++ b/tests/unit_tests/openvpn/Makefile.am @@ -6,7 +6,8 @@ if HAVE_LD_WRAP_SUPPORT test_binaries += argv_testdriver buffer_testdriver endif -test_binaries += crypto_testdriver packet_id_testdriver auth_token_testdriver ncp_testdriver misc_testdriver +test_binaries += crypto_testdriver packet_id_testdriver auth_token_testdriver ncp_testdriver misc_testdriver \ + pkt_testdriver if HAVE_LD_WRAP_SUPPORT test_binaries += tls_crypt_testdriver endif @@ -62,6 +63,27 @@ packet_id_testdriver_SOURCES = test_packet_id.c mock_msg.c mock_msg.h \ $(openvpn_srcdir)/packet_id.c \ $(openvpn_srcdir)/platform.c +pkt_testdriver_CFLAGS = @TEST_CFLAGS@ \ + -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) +pkt_testdriver_LDFLAGS = @TEST_LDFLAGS@ +pkt_testdriver_SOURCES = test_pkt.c mock_msg.c mock_msg.h \ +$(openvpn_srcdir)/argv.c \ + $(openvpn_srcdir)/base64.c \ + $(openvpn_srcdir)/buffer.c \ + $(openvpn_srcdir)/crypto.c \ + $(openvpn_srcdir)/crypto_mbedtls.c \ + $(openvpn_srcdir)/crypto_openssl.c \ + $(openvpn_srcdir)/env_set.c \ + $(openvpn_srcdir)/otime.c \ + $(openvpn_srcdir)/packet_id.c \ + $(openvpn_srcdir)/platform.c \ + $(openvpn_srcdir)/reliable.c \ + $(openvpn_srcdir)/run_command.c \ + $(openvpn_srcdir)/session_id.c \ + $(openvpn_srcdir)/ssl_pkt.c \ + $(openvpn_srcdir)/tls_crypt.c + + tls_crypt_testdriver_CFLAGS = @TEST_CFLAGS@ \ -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) tls_crypt_testdriver_LDFLAGS = @TEST_LDFLAGS@ \ diff --git a/tests/unit_tests/openvpn/test_pkt.c b/tests/unit_tests/openvpn/test_pkt.c new file mode 100644 index 000000000..022e15d3e --- /dev/null +++ b/tests/unit_tests/openvpn/test_pkt.c @@ -0,0 +1,347 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2016-2021 Fox Crypto B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" + +#include +#include +#include +#include +#include +#include + +#include "crypto.h" +#include "options.h" +#include "ssl_backend.h" +#include "ssl_pkt.h" +#include "tls_crypt.h" + +#include "mock_msg.h" +#include "mss.h" + +int +parse_line(const char *line, char **p, const int n, const char *file, + const int line_num, int msglevel, struct gc_arena *gc) +{ + /* Dummy function to get the linker happy, should never be called */ + assert_true(false); + return 0; +} + +const char * +print_link_socket_actual(const struct link_socket_actual *act, struct gc_arena *gc) +{ + return "dummy print_link_socket_actual from unit test"; +} + +struct test_pkt_context { + struct tls_auth_standalone tas_tls_auth; + struct tls_auth_standalone tas_crypt; +}; + +const char static_key[] = "\n" + "-----BEGIN OpenVPN Static key V1-----\n" + "37268ea8f95d7f71f9fb8fc03770c460\n" + "daf714a483d815c013ce0a537efc18f2\n" + "8f4f172669d9e6a413bac6741d8ea054\n" + "00f49b7fd6326470f23798c606bf53d4\n" + "de63ebc64ec59d57ce5d04d5b62e68b5\n" + "3ca6e5354351097fa370446c4d269f18\n" + "7bb6ae54af2dc70ff7317fe2f8754b82\n" + "82aad4202f9fa42c8640245d883e2c54\n" + "a0c1c489a036cf3a8964d8d289c1583b\n" + "9447c262b1da5fd167a5d27bd5ac5143\n" + "17bc2343a31a2efc38dd920d910375f5\n" + "1c2e27f3afd36c49269da079f7ce466e\n" + "bb0f9ad13e9bbb4665974e6bc24b513c\n" + "5700393bf4a3e7f967e2f384069ac8a8\n" + "e78b18b15604993fd16515cce9c0f3e4\n" + "2b4126b999005ade802797b0eeb8b9e6\n" + "-----END OpenVPN Static key V1-----\n" + "\n"; + +const uint8_t client_reset_v2_none[] = + { 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}; + +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}; + +/* Valid tls-auth client CONTROL_V1 packet with random server id */ +const uint8_t client_ack_tls_auth_randomid[] = { + 0x20, 0x14, 0x01, 0x4e, 0xbc, 0x80, 0xc6, 0x14, + 0x2b, 0x7b, 0xc8, 0x76, 0xfb, 0xc5, 0x2e, 0x27, + 0xb1, 0xc5, 0x07, 0x35, 0x5b, 0xb6, 0x00, 0x6b, + 0xae, 0x71, 0xba, 0x4e, 0x38, 0x00, 0x00, 0x00, + 0x03, 0x61, 0xd3, 0xff, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x16, 0x03, 0x01, 0x01, 0x0c, 0x01, + 0x00, 0x01, 0x08, 0x03, 0x03, 0x8c, 0xaa, 0xac, + 0x3a, 0x1a, 0x07, 0xbd, 0xe7, 0xb7, 0x50, 0x06, + 0x9b, 0x94, 0x0c, 0x34, 0x4b, 0x5a, 0x35, 0xca, + 0xc4, 0x79, 0xbd, 0xc9, 0x09, 0xb0, 0x7b, 0xd9, + 0xee, 0xbb, 0x7d, 0xe7, 0x25, 0x20, 0x39, 0x38, + 0xe2, 0x18, 0x33, 0x36, 0x14, 0x9f, 0x34, 0xf0, + 0x44, 0x59, 0x96, 0x8d, 0x0e, 0xd2, 0x47, 0x76, + 0x64, 0x88, 0x59, 0xe9, 0x38, 0x03, 0x97, 0x96, + 0x98, 0x45, 0xfb, 0xf5, 0xff, 0x23, 0x00, 0x32, + 0x13, 0x02, 0x13, 0x03, 0x13, 0x01, 0xc0, 0x2c, + 0xc0, 0x30, 0x00, 0x9f, 0xcc, 0xa9, 0xcc, 0xa8, + 0xcc, 0xaa, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e, + 0xc0, 0x24, 0xc0, 0x28, 0x00, 0x6b, 0xc0, 0x23, + 0xc0, 0x27, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x14, + 0x00, 0x39, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x33, + 0x00, 0xff, 0x01, 0x00, 0x00, 0x8d, 0x00, 0x0b, + 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, + 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x1d, 0x00, 0x17, + 0x00, 0x1e, 0x00, 0x19, 0x00, 0x18, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x30, 0x00, 0x2e, 0x04, 0x03, 0x05, 0x03, + 0x06, 0x03, 0x08, 0x07, 0x08, 0x08, 0x08, 0x09, + 0x08, 0x0a, 0x08, 0x0b, 0x08, 0x04, 0x08, 0x05, + 0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, + 0x03, 0x03, 0x02, 0x03, 0x03, 0x01, 0x02, 0x01, + 0x03, 0x02, 0x02, 0x02, 0x04, 0x02, 0x05, 0x02, + 0x06, 0x02, 0x00, 0x2b, 0x00, 0x05, 0x04, 0x03, + 0x04, 0x03, 0x03, 0x00, 0x2d, 0x00, 0x02, 0x01, + 0x01, 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, + 0x1d, 0x00, 0x20, 0x0e, 0xc9, 0x7a, 0xff, 0x58, + 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}; + +struct tls_auth_standalone init_tas_auth(int key_direction) +{ + struct tls_auth_standalone tas = { 0 }; + + 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; + + struct key_type tls_crypt_kt; + init_key_type(&tls_crypt_kt, "none", "SHA1", true, false); + + crypto_read_openvpn_key(&tls_crypt_kt, &tas.tls_wrap.opt.key_ctx_bi, + static_key, true, key_direction, + "Control Channel Authentication", "tls-auth"); + return tas; +} + +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; + + tls_crypt_init_key(&tas.tls_wrap.opt.key_ctx_bi, static_key, true, server); + + return tas; +} + +void +test_tls_decrypt_lite_crypt(void **ut_state) +{ + struct link_socket_actual from = { 0 }; + struct tls_pre_decrypt_state state = { 0 }; + + struct tls_auth_standalone tas = init_tas_crypt(true); + + struct buffer buf = alloc_buf(1024); + + /* tls-auth should be invalid */ + buf_write(&buf, client_reset_v2_tls_auth, sizeof(client_reset_v2_tls_auth)); + enum first_packet_verdict verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_INVALID); + free_tls_pre_decrypt_state(&state); + + /* as well as the too short normal reset */ + buf_reset_len(&buf); + buf_write(&buf, client_reset_v2_none, sizeof(client_reset_v2_none)); + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_INVALID); + free_tls_pre_decrypt_state(&state); + + /* the tls-crypt should validate */ + buf_reset_len(&buf); + buf_write(&buf, client_reset_v2_tls_crypt, sizeof(client_reset_v2_tls_crypt)); + verdict = tls_pre_decrypt_lite(&tas, &state, &from, &buf); + assert_int_equal(verdict, VERDICT_VALID_RESET); + free_tls_pre_decrypt_state(&state); + + /* flip a byte in various places */ + for (int i=0;i