2014-08-25 09:02:40 +02:00
// OpenVPN -- An application to securely tunnel IP networks
// over a single port, with support for SSL/TLS-based
// session authentication and key exchange,
// packet encryption, packet authentication, and
// packet compression.
2013-01-31 16:00:45 +01:00
//
2023-06-06 18:31:22 +02:00
// Copyright (C) 2012-2023 OpenVPN Inc.
2013-01-31 16:00:45 +01:00
//
2014-08-25 09:02:40 +02:00
// This program is free software: you can redistribute it and/or modify
2017-12-21 21:42:20 +01:00
// it under the terms of the GNU Affero General Public License Version 3
2014-08-25 09:02:40 +02:00
// as published by the Free Software Foundation.
2013-01-31 16:00:45 +01:00
//
2014-08-25 09:02:40 +02:00
// 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
2017-12-21 21:42:20 +01:00
// GNU Affero General Public License for more details.
2014-08-25 09:02:40 +02:00
//
2017-12-21 21:42:20 +01:00
// You should have received a copy of the GNU Affero General Public License
2014-08-25 09:02:40 +02:00
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
2013-01-31 16:00:45 +01:00
2013-01-30 17:24:37 +01:00
// Unit test for OpenVPN Protocol implementation (class ProtoContext)
2023-06-06 18:31:22 +02:00
# include "test_common.h"
2011-12-11 09:28:55 +01:00
# include <iostream>
# include <string>
# include <sstream>
# include <deque>
# include <algorithm>
# include <cstring>
# include <limits>
2015-05-11 04:04:22 +02:00
# include <thread>
2011-12-11 09:28:55 +01:00
2024-02-07 18:30:43 +01:00
# include <gmock/gmock.h>
2014-03-04 02:43:13 +01:00
# include <openvpn/common/platform.hpp>
2024-02-07 18:30:43 +01:00
# include <openvpn/ssl/sslchoose.hpp>
2014-03-04 02:43:13 +01:00
2017-03-24 10:00:39 +01:00
2024-02-07 18:30:43 +01:00
# define OPENVPN_DEBUG
2021-12-28 23:57:01 +01:00
2017-03-24 10:00:39 +01:00
# if !defined(USE_TLS_AUTH) && !defined(USE_TLS_CRYPT)
// #define USE_TLS_AUTH
2017-06-30 05:13:22 +02:00
// #define USE_TLS_CRYPT
# define USE_TLS_CRYPT_V2
2017-03-24 10:00:39 +01:00
# endif
2016-09-01 23:19:00 +02:00
// Data limits for Blowfish and other 64-bit block-size ciphers
# ifndef BF
# define BF 0
# endif
# define OPENVPN_BS64_DATA_LIMIT 50000
# if BF == 1
# define PROTO_CIPHER "BF-CBC"
# define TLS_VER_MIN TLSVersion::UNDEF
# define HANDSHAKE_WINDOW 60
# define BECOME_PRIMARY_CLIENT 5
# define BECOME_PRIMARY_SERVER 5
# define TLS_TIMEOUT_CLIENT 1000
# define TLS_TIMEOUT_SERVER 1000
# define FEEDBACK 0
# elif BF == 2
# define PROTO_CIPHER "BF-CBC"
# define TLS_VER_MIN TLSVersion::UNDEF
# define HANDSHAKE_WINDOW 10
# define BECOME_PRIMARY_CLIENT 10
# define BECOME_PRIMARY_SERVER 10
# define TLS_TIMEOUT_CLIENT 2000
# define TLS_TIMEOUT_SERVER 1000
# define FEEDBACK 0
# elif BF == 3
# define PROTO_CIPHER "BF-CBC"
# define TLS_VER_MIN TLSVersion::UNDEF
# define HANDSHAKE_WINDOW 60
# define BECOME_PRIMARY_CLIENT 60
# define BECOME_PRIMARY_SERVER 10
# define TLS_TIMEOUT_CLIENT 2000
# define TLS_TIMEOUT_SERVER 1000
# define FEEDBACK 0
# elif BF != 0
# error unknown BF value
# endif
// TLS timeout
# ifndef TLS_TIMEOUT_CLIENT
# define TLS_TIMEOUT_CLIENT 2000
# endif
# ifndef TLS_TIMEOUT_SERVER
# define TLS_TIMEOUT_SERVER 2000
# endif
2011-12-11 09:28:55 +01:00
2014-10-21 04:30:13 +02:00
// NoisyWire
2014-12-31 02:15:05 +01:00
# ifndef NOERR
2014-10-21 04:30:13 +02:00
# define SIMULATE_OOO
# define SIMULATE_DROPPED
# define SIMULATE_CORRUPTED
2014-12-31 02:15:05 +01:00
# endif
2012-03-11 13:09:25 +01:00
2014-03-03 22:43:38 +01:00
// how many virtual seconds between SSL renegotiations
2024-02-07 18:30:43 +01:00
# ifdef PROTO_RENEG
# define RENEG PROTO_RENEG
# else
2014-03-05 01:42:00 +01:00
# define RENEG 900
2014-03-03 22:43:38 +01:00
# endif
2016-09-01 23:19:00 +02:00
// feedback
# ifndef FEEDBACK
# define FEEDBACK 1
# else
# define FEEDBACK 0
# endif
2011-12-13 12:13:27 +01:00
// number of iterations
2024-02-07 18:30:43 +01:00
# ifdef PROTO_ITER
# define ITER PROTO_ITER
# else
2011-12-13 05:46:56 +01:00
# define ITER 1000000
# endif
2011-12-17 11:53:21 +01:00
// number of high-level session iterations
2024-02-07 18:30:43 +01:00
# ifdef PROTO_SITER
# define SITER PROTO_SITER
# else
2011-12-17 11:53:21 +01:00
# define SITER 1
# endif
2021-06-01 07:21:30 +02:00
// number of retries for failed test
# ifndef N_RETRIES
2024-02-07 18:30:43 +01:00
# define N_RETRIES 2
2021-06-01 07:21:30 +02:00
# endif
2023-06-06 18:31:22 +02:00
// potentially, the above manifest constants can be converted to variables and modified
// within the different TEST() functions that replace main() in the original file
2011-12-17 11:53:21 +01:00
// abort if we reach this limit
// #define DROUGHT_LIMIT 100000
2024-02-07 18:30:43 +01:00
# if !defined(PROTO_VERBOSE) && !defined(QUIET) && ITER <= 10000
2011-12-13 05:46:56 +01:00
# define VERBOSE
# endif
2012-03-26 00:07:45 +02:00
# define STRINGIZE1(x) #x
# define STRINGIZE(x) STRINGIZE1(x)
// setup cipher
# ifndef PROTO_CIPHER
2014-12-21 18:32:37 +01:00
# ifdef PROTOv2
2016-09-01 23:19:00 +02:00
# define PROTO_CIPHER "AES-256-GCM"
2023-03-11 13:56:40 +01:00
# define TLS_VER_MIN TLSVersion::Type::V1_2
2014-12-21 18:32:37 +01:00
# else
2016-09-01 23:19:00 +02:00
# define PROTO_CIPHER "AES-128-CBC"
2023-03-11 13:56:40 +01:00
# define TLS_VER_MIN TLSVersion::Type::UNDEF
2012-03-26 00:07:45 +02:00
# endif
2014-12-21 18:32:37 +01:00
# endif
2012-03-26 00:07:45 +02:00
// setup digest
# ifndef PROTO_DIGEST
2016-09-01 23:19:00 +02:00
# define PROTO_DIGEST "SHA1"
2012-03-23 21:04:33 +01:00
# endif
2014-12-21 18:32:37 +01:00
// setup compressor
# ifdef PROTOv2
# ifdef HAVE_LZ4
# define COMP_METH CompressContext::LZ4v2
# else
# define COMP_METH CompressContext::COMP_STUBv2
# endif
# else
# define COMP_METH CompressContext::LZO_STUB
# endif
2011-12-11 09:28:55 +01:00
# include <openvpn/common/exception.hpp>
# include <openvpn/common/file.hpp>
2015-05-17 21:17:24 +02:00
# include <openvpn/common/count.hpp>
2011-12-11 09:28:55 +01:00
# include <openvpn/time/time.hpp>
2016-06-29 06:31:17 +02:00
# include <openvpn/random/mtrandapi.hpp>
2011-12-11 09:28:55 +01:00
# include <openvpn/frame/frame.hpp>
# include <openvpn/ssl/proto.hpp>
2012-03-12 13:24:40 +01:00
# include <openvpn/init/initprocess.hpp>
2011-12-11 09:28:55 +01:00
2014-10-17 23:52:29 +02:00
# include <openvpn/crypto/cryptodcsel.hpp>
2014-10-08 21:43:40 +02:00
2017-02-24 00:59:51 +01:00
# if defined(USE_MBEDTLS_APPLE_HYBRID)
# define USE_MBEDTLS
2014-10-22 00:41:05 +02:00
# endif
2017-02-24 00:59:51 +01:00
# if !(defined(USE_OPENSSL) || defined(USE_MBEDTLS) || defined(USE_APPLE_SSL))
# error Must define one or more of USE_OPENSSL, USE_MBEDTLS, USE_APPLE_SSL.
2014-03-05 01:42:00 +01:00
# endif
2017-02-24 00:59:51 +01:00
# if defined(USE_OPENSSL) && (defined(USE_MBEDTLS) || defined(USE_APPLE_SSL))
2014-03-05 01:42:00 +01:00
# undef USE_OPENSSL
# define USE_OPENSSL_SERVER
2017-02-24 00:59:51 +01:00
# elif !defined(USE_OPENSSL) && defined(USE_MBEDTLS)
# define USE_MBEDTLS_SERVER
# elif defined(USE_OPENSSL) && !defined(USE_MBEDTLS)
2014-03-05 01:42:00 +01:00
# define USE_OPENSSL_SERVER
# else
# error no server setup
# endif
2012-09-15 08:56:18 +02:00
# if defined(USE_OPENSSL) || defined(USE_OPENSSL_SERVER)
2012-03-13 05:51:52 +01:00
# include <openvpn/openssl/util/init.hpp>
2012-03-12 13:24:40 +01:00
# include <openvpn/openssl/crypto/api.hpp>
2011-12-11 09:28:55 +01:00
# include <openvpn/openssl/ssl/sslctx.hpp>
2012-03-11 13:09:25 +01:00
# include <openvpn/openssl/util/rand.hpp>
2011-12-13 05:46:56 +01:00
2012-09-15 08:56:18 +02:00
# endif
2012-03-14 01:51:40 +01:00
2017-02-24 00:59:51 +01:00
# if defined(USE_APPLE_SSL) || defined(USE_MBEDTLS_APPLE_HYBRID)
2012-03-13 05:51:52 +01:00
# include <openvpn/applecrypto/crypto/api.hpp>
2011-12-11 09:28:55 +01:00
# include <openvpn/applecrypto/ssl/sslctx.hpp>
2012-03-11 13:09:25 +01:00
# include <openvpn/applecrypto/util/rand.hpp>
# endif
2017-02-24 00:59:51 +01:00
# if defined(USE_MBEDTLS) || defined(USE_MBEDTLS_SERVER)
# include <openvpn/mbedtls/crypto/api.hpp>
# include <openvpn/mbedtls/ssl/sslctx.hpp>
# include <openvpn/mbedtls/util/rand.hpp>
mbedTLS: Port from polarssl-1.3 to mbedtls-2.3 (functional)
This patch builds on work by David Sommerseth <davids@openvpn.net>
to move the PolarSSL API from polarssl-1.3 to mbedtls-2.3, which
has significant differences in some areas.
- Strings containing keys, certificates, CRLs, and DH parameters
need to be NULL-terminated and the length argument provided to
the corresponding mbedtls parse function must be able to read
the NULL-terminator. These places have been modified with a
'+1' to the length argument (x509cert.hpp, x509crl.hpp, dh.hpp,
pkctx.hpp).
- The SSL context object has been split up in mbedtls-2.3
Now many of the SSL configurations are done in a separate
SSL config object, which is added to the SSL context once
configured. In addition private/public keys are now stored
in a separate pk_context, which is later on attached to the
SSL context. Due to this, many of the calls setting either
SSL configuration parameters or working with pk_contexts have
been refactored. (sslctx.hpp)
- The older API loading the CA chain took a hostname argument.
The new API requires mbedtls_ssl_set_hostname() explicitly to
be called setting hostname. Some refactoring was needed here
too (sslctx.hpp).
- x509_oid_get_description() is now replaced by
mbedtls_oid_get_extended_key_usage().
- when mbedTLS renamed OID_CMP to MBEDTLS_OID_CMP, the return
value was changed so that a return value of 0 now means equal
rather than not-equal.
- mbedtls/platform.h must be loaded before any other mbedtls
include files (sslchoose.hpp).
- All functions and macros related to mbedTLS are now prefixed
with mbedtls_/MBEDTLS_
- Refactored External PKI and added some options to cli.cpp
to make it easier to test that the feature still works
correctly. This included removing the sig_type var and
standardizing on a PKCS#1 digest prefix per RFC 3447.
- Updated test keys to 2048 bits.
- Updated dependency build scripts to build mbedTLS.
- Enable MD4 in mbedTLS build script (needed for NTLM auth).
- Use an allow-all X509 cert profile to preserve compatibility
with older configs. Going forward, we will implement new
options to increase strictness on minimum RSA key size and
required cert signing algs.
- Added human-readable reason strings that explain why
a given cert in the chain wasn't accepted.
- This patch doesn't rename any files or rename internal
OpenVPN 3 symbols such as PolarSSLContext. This will
be done in a separate commit.
Signed-off-by: James Yonan <james@openvpn.net>
2017-02-23 23:20:31 +01:00
# include <mbedtls/debug.h>
2011-12-11 09:28:55 +01:00
# endif
2014-03-04 18:42:07 +01:00
# include <openvpn/crypto/selftest.hpp>
2011-12-13 05:46:56 +01:00
using namespace openvpn ;
2011-12-11 09:28:55 +01:00
2014-03-05 01:42:00 +01:00
// server Crypto/SSL/Rand implementation
2017-02-24 00:59:51 +01:00
# if defined(USE_MBEDTLS_SERVER)
typedef MbedTLSCryptoAPI ServerCryptoAPI ;
typedef MbedTLSContext ServerSSLAPI ;
typedef MbedTLSRandom ServerRandomAPI ;
2014-03-05 01:42:00 +01:00
# elif defined(USE_OPENSSL_SERVER)
2012-03-12 13:24:40 +01:00
typedef OpenSSLCryptoAPI ServerCryptoAPI ;
typedef OpenSSLContext ServerSSLAPI ;
typedef OpenSSLRandom ServerRandomAPI ;
2014-03-05 01:42:00 +01:00
# else
# error No server SSL implementation defined
2012-09-15 08:56:18 +02:00
# endif
2011-12-18 11:50:08 +01:00
2017-02-24 00:59:51 +01:00
// client SSL implementation can be OpenSSL, Apple SSL, or MbedTLS
# if defined(USE_MBEDTLS)
# if defined(USE_MBEDTLS_APPLE_HYBRID)
2014-10-22 00:41:05 +02:00
typedef AppleCryptoAPI ClientCryptoAPI ;
# else
2017-02-24 00:59:51 +01:00
typedef MbedTLSCryptoAPI ClientCryptoAPI ;
2014-10-22 00:41:05 +02:00
# endif
2017-02-24 00:59:51 +01:00
typedef MbedTLSContext ClientSSLAPI ;
typedef MbedTLSRandom ClientRandomAPI ;
2012-03-11 13:09:25 +01:00
# elif defined(USE_APPLE_SSL)
2012-03-15 13:13:16 +01:00
typedef AppleCryptoAPI ClientCryptoAPI ;
2012-03-12 13:24:40 +01:00
typedef AppleSSLContext ClientSSLAPI ;
typedef AppleRandom ClientRandomAPI ;
2012-03-13 05:51:52 +01:00
# elif defined(USE_OPENSSL)
typedef OpenSSLCryptoAPI ClientCryptoAPI ;
typedef OpenSSLContext ClientSSLAPI ;
typedef OpenSSLRandom ClientRandomAPI ;
2011-12-18 11:50:08 +01:00
# else
2012-03-11 13:09:25 +01:00
# error No client SSL implementation defined
2011-12-18 11:50:08 +01:00
# endif
2011-12-11 09:28:55 +01:00
const char message [ ] = " Message _->_ 0000000000 It was a bright cold day in April, and the clocks \n "
" were striking thirteen. Winston Smith, his chin nuzzled \n "
" into his breast in an effort to escape the vile wind, \n "
" slipped quickly through the glass doors of Victory \n "
" Mansions, though not quickly enough to prevent a \n "
" swirl of gritty dust from entering along with him. \n "
# ifdef LARGE_MESSAGE
" It was a bright cold day in April, and the clocks \n "
" were striking thirteen. Winston Smith, his chin nuzzled \n "
" into his breast in an effort to escape the vile wind, \n "
" slipped quickly through the glass doors of Victory \n "
" Mansions, though not quickly enough to prevent a \n "
" swirl of gritty dust from entering along with him. \n "
" It was a bright cold day in April, and the clocks \n "
" were striking thirteen. Winston Smith, his chin nuzzled \n "
" into his breast in an effort to escape the vile wind, \n "
" slipped quickly through the glass doors of Victory \n "
" Mansions, though not quickly enough to prevent a \n "
" swirl of gritty dust from entering along with him. \n "
" It was a bright cold day in April, and the clocks \n "
" were striking thirteen. Winston Smith, his chin nuzzled \n "
" into his breast in an effort to escape the vile wind, \n "
" slipped quickly through the glass doors of Victory \n "
" Mansions, though not quickly enough to prevent a \n "
" swirl of gritty dust from entering along with him. \n "
" It was a bright cold day in April, and the clocks \n "
" were striking thirteen. Winston Smith, his chin nuzzled \n "
" into his breast in an effort to escape the vile wind, \n "
" slipped quickly through the glass doors of Victory \n "
" Mansions, though not quickly enough to prevent a \n "
" swirl of gritty dust from entering along with him. \n "
# endif
;
2011-12-13 12:13:27 +01:00
// A "Drought" measures the maximum period of time between
// any two successive events. Used to measure worst-case
// packet loss.
2011-12-13 05:46:56 +01:00
class DroughtMeasure
{
public :
2011-12-17 11:53:21 +01:00
OPENVPN_SIMPLE_EXCEPTION ( drought_limit_exceeded ) ;
2023-01-11 20:43:22 +01:00
2011-12-17 11:53:21 +01:00
DroughtMeasure ( const std : : string & name_arg , TimePtr now_arg )
: now ( now_arg ) , name ( name_arg )
2011-12-13 05:46:56 +01:00
{
}
2023-01-11 20:43:22 +01:00
2011-12-13 05:46:56 +01:00
void event ( )
{
if ( last_event . defined ( ) )
{
Time : : Duration since_last = * now - last_event ;
if ( since_last > drought )
2011-12-17 11:53:21 +01:00
{
drought = since_last ;
# if defined(VERBOSE) || defined(DROUGHT_LIMIT)
{
const unsigned int r = drought . raw ( ) ;
2016-09-01 23:19:00 +02:00
# if defined(VERBOSE)
2011-12-17 11:53:21 +01:00
std : : cout < < " *** Drought " < < name < < " has reached " < < r < < std : : endl ;
# endif
# ifdef DROUGHT_LIMIT
if ( r > DROUGHT_LIMIT )
throw drought_limit_exceeded ( ) ;
# endif
}
# endif
}
2011-12-13 05:46:56 +01:00
}
last_event = * now ;
}
Time : : Duration operator ( ) ( ) const
{
return drought ;
}
private :
TimePtr now ;
Time last_event ;
Time : : Duration drought ;
2011-12-17 11:53:21 +01:00
std : : string name ;
2011-12-13 05:46:56 +01:00
} ;
2011-12-13 12:13:27 +01:00
// test the OpenVPN protocol implementation in ProtoContext
2024-02-22 07:26:46 +01:00
class TestProto : public ProtoContextCallbackInterface
2011-12-11 09:28:55 +01:00
{
2024-02-22 07:26:46 +01:00
/* Callback methods that are not used */
void active ( bool primary ) override
{
}
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
public :
2016-09-01 23:19:00 +02:00
OPENVPN_EXCEPTION ( session_invalidated ) ;
2023-01-11 20:43:22 +01:00
2024-02-22 07:26:46 +01:00
TestProto ( const ProtoContext : : ProtoConfig : : Ptr & config ,
2012-02-04 11:24:54 +01:00
const SessionStats : : Ptr & stats )
2024-02-22 07:26:46 +01:00
: proto_context ( this , config , stats ) ,
2011-12-17 11:53:21 +01:00
control_drought ( " control " , config - > now ) ,
data_drought ( " data " , config - > now ) ,
2016-09-01 23:19:00 +02:00
frame ( config - > frame )
2011-12-11 09:28:55 +01:00
{
// zero progress value
std : : memset ( progress_ , 0 , 11 ) ;
}
2023-01-11 20:43:22 +01:00
2011-12-17 11:53:21 +01:00
void reset ( )
{
net_out . clear ( ) ;
2024-02-22 07:26:46 +01:00
proto_context . reset ( ) ;
proto_context . conf ( ) . mss_parms . mssfix = MSSParms : : MSSFIX_DEFAULT ;
2011-12-17 11:53:21 +01:00
}
2023-01-11 20:43:22 +01:00
2011-12-17 11:53:21 +01:00
void initial_app_send ( const char * msg )
{
2024-02-22 07:26:46 +01:00
proto_context . start ( ) ;
2016-05-10 05:39:04 +02:00
const size_t msglen = std : : strlen ( msg ) + 1 ;
2011-12-17 11:53:21 +01:00
BufferAllocated app_buf ( ( unsigned char * ) msg , msglen , 0 ) ;
copy_progress ( app_buf ) ;
2016-05-10 21:02:11 +02:00
control_send ( std : : move ( app_buf ) ) ;
2024-02-22 07:26:46 +01:00
proto_context . flush ( true ) ;
2011-12-17 11:53:21 +01:00
}
2023-01-11 20:43:22 +01:00
2016-09-01 23:19:00 +02:00
void app_send_templ_init ( const char * msg )
{
2024-02-22 07:26:46 +01:00
proto_context . start ( ) ;
2016-09-01 23:19:00 +02:00
const size_t msglen = std : : strlen ( msg ) + 1 ;
templ . reset ( new BufferAllocated ( ( unsigned char * ) msg , msglen , 0 ) ) ;
2024-02-22 07:26:46 +01:00
proto_context . flush ( true ) ;
2016-09-01 23:19:00 +02:00
}
2023-01-11 20:43:22 +01:00
2016-09-01 23:19:00 +02:00
void app_send_templ ( )
{
# if !FEEDBACK
if ( bool ( iteration + + & 1 ) = = is_server ( ) )
2011-12-15 09:48:14 +01:00
{
2016-05-10 21:02:11 +02:00
modmsg ( templ ) ;
BufferAllocated app_buf ( * templ ) ;
2011-12-11 09:28:55 +01:00
control_send ( std : : move ( app_buf ) ) ;
flush ( true ) ;
2016-09-01 23:19:00 +02:00
+ + n_control_send_ ;
2021-06-12 00:40:59 +02:00
}
# endif
2011-12-11 09:28:55 +01:00
}
bool do_housekeeping ( )
2023-01-11 20:43:22 +01:00
{
2024-02-22 07:26:46 +01:00
if ( proto_context . now ( ) > = proto_context . next_housekeeping ( ) )
2023-01-11 20:43:22 +01:00
{
2024-02-22 07:26:46 +01:00
proto_context . housekeeping ( ) ;
2011-12-15 09:48:14 +01:00
return true ;
2023-01-11 20:43:22 +01:00
}
else
2011-12-15 09:48:14 +01:00
return false ;
2023-01-11 20:43:22 +01:00
}
2016-05-10 21:02:11 +02:00
void control_send ( BufferPtr & & app_bp )
2023-01-11 20:43:22 +01:00
{
2011-12-11 09:28:55 +01:00
app_bytes_ + = app_bp - > size ( ) ;
2024-02-22 07:26:46 +01:00
proto_context . control_send ( std : : move ( app_bp ) ) ;
2023-01-11 20:43:22 +01:00
}
2016-05-10 21:02:11 +02:00
void control_send ( BufferAllocated & & app_buf )
2023-01-11 20:43:22 +01:00
{
2011-12-11 09:28:55 +01:00
app_bytes_ + = app_buf . size ( ) ;
2024-02-22 07:26:46 +01:00
proto_context . control_send ( std : : move ( app_buf ) ) ;
2023-01-11 20:43:22 +01:00
}
2011-12-11 09:28:55 +01:00
BufferPtr data_encrypt_string ( const char * str )
2023-01-11 20:43:22 +01:00
{
2011-12-11 09:28:55 +01:00
BufferPtr bp = new BufferAllocated ( ) ;
frame - > prepare ( Frame : : READ_LINK_UDP , * bp ) ;
bp - > write ( ( unsigned char * ) str , std : : strlen ( str ) ) ;
data_encrypt ( * bp ) ;
return bp ;
2023-01-11 20:43:22 +01:00
}
2011-12-11 09:28:55 +01:00
void data_encrypt ( BufferAllocated & in_out )
2023-01-11 20:43:22 +01:00
{
2024-02-22 07:26:46 +01:00
proto_context . data_encrypt ( in_out ) ;
2023-01-11 20:43:22 +01:00
}
2024-02-22 07:26:46 +01:00
void data_decrypt ( const ProtoContext : : PacketType & type , BufferAllocated & in_out )
2023-01-11 20:43:22 +01:00
{
2024-02-22 07:26:46 +01:00
proto_context . data_decrypt ( type , in_out ) ;
2011-12-13 05:46:56 +01:00
if ( in_out . size ( ) )
2023-01-11 20:43:22 +01:00
{
2011-12-14 12:34:33 +01:00
data_bytes_ + = in_out . size ( ) ;
data_drought . event ( ) ;
2023-01-11 20:43:22 +01:00
}
}
2011-12-11 09:28:55 +01:00
size_t net_bytes ( ) const
2023-01-11 20:43:22 +01:00
{
2011-12-11 09:28:55 +01:00
return net_bytes_ ;
2023-01-11 20:43:22 +01:00
}
2011-12-11 09:28:55 +01:00
size_t app_bytes ( ) const
2023-01-11 20:43:22 +01:00
{
2011-12-11 09:28:55 +01:00
return app_bytes_ ;
2023-01-11 20:43:22 +01:00
}
2011-12-11 09:28:55 +01:00
size_t data_bytes ( ) const
2023-01-11 20:43:22 +01:00
{
2011-12-11 09:28:55 +01:00
return data_bytes_ ;
2023-01-11 20:43:22 +01:00
}
2016-09-01 23:19:00 +02:00
size_t n_control_recv ( ) const
2023-01-11 20:43:22 +01:00
{
2016-09-01 23:19:00 +02:00
return n_control_recv_ ;
2023-01-11 20:43:22 +01:00
}
2016-09-01 23:19:00 +02:00
size_t n_control_send ( ) const
2023-01-11 20:43:22 +01:00
{
2016-09-01 23:19:00 +02:00
return n_control_send_ ;
2023-01-11 20:43:22 +01:00
}
2011-12-11 09:28:55 +01:00
const char * progress ( ) const
2023-01-11 20:43:22 +01:00
{
2011-12-11 09:28:55 +01:00
return progress_ ;
2023-01-11 20:43:22 +01:00
}
2011-12-13 05:46:56 +01:00
void finalize ( )
2023-01-11 20:43:22 +01:00
{
2011-12-13 05:46:56 +01:00
data_drought . event ( ) ;
control_drought . event ( ) ;
2023-01-11 20:43:22 +01:00
}
2016-09-01 23:19:00 +02:00
void check_invalidated ( )
2023-01-11 20:43:22 +01:00
{
2024-02-22 07:26:46 +01:00
if ( proto_context . invalidated ( ) )
throw session_invalidated ( Error : : name ( proto_context . invalidation_reason ( ) ) ) ;
2023-01-11 20:43:22 +01:00
}
2021-06-12 00:40:59 +02:00
void disable_xmit ( )
2011-12-11 09:28:55 +01:00
{
disable_xmit_ = true ;
}
2023-01-11 20:43:22 +01:00
2024-02-22 07:26:46 +01:00
ProtoContext proto_context ;
2011-12-11 09:28:55 +01:00
std : : deque < BufferPtr > net_out ;
2023-01-11 20:43:22 +01:00
2011-12-13 05:46:56 +01:00
DroughtMeasure control_drought ;
DroughtMeasure data_drought ;
2023-01-11 20:43:22 +01:00
private :
2024-02-22 07:26:46 +01:00
void control_net_send ( const Buffer & net_buf ) override
2023-01-11 20:43:22 +01:00
{
2021-06-12 00:40:59 +02:00
if ( disable_xmit_ )
2023-01-11 20:43:22 +01:00
return ;
2011-12-11 09:28:55 +01:00
net_bytes_ + = net_buf . size ( ) ;
net_out . push_back ( BufferPtr ( new BufferAllocated ( net_buf , 0 ) ) ) ;
2023-01-11 20:43:22 +01:00
}
2024-02-22 07:26:46 +01:00
void control_recv ( BufferPtr & & app_bp ) override
2023-01-11 20:43:22 +01:00
{
2011-12-11 09:28:55 +01:00
BufferPtr work ;
work . swap ( app_bp ) ;
if ( work - > size ( ) > = 23 )
std : : memcpy ( progress_ , work - > data ( ) + 13 , 10 ) ;
2023-01-11 20:43:22 +01:00
2011-12-14 17:20:07 +01:00
# ifdef VERBOSE
2023-01-11 20:43:22 +01:00
{
2011-12-11 09:28:55 +01:00
const ssize_t trunc = 64 ;
const std : : string show ( ( char * ) work - > data ( ) , trunc ) ;
2011-12-18 11:50:08 +01:00
std : : cout < < now ( ) . raw ( ) < < " " < < mode ( ) . str ( ) < < " " < < show < < std : : endl ;
2023-01-11 20:43:22 +01:00
}
2011-12-11 09:28:55 +01:00
# endif
2016-09-01 23:19:00 +02:00
# if FEEDBACK
2011-12-11 09:28:55 +01:00
modmsg ( work ) ;
2016-05-10 21:02:11 +02:00
control_send ( std : : move ( work ) ) ;
2016-09-01 23:19:00 +02:00
# endif
2011-12-13 05:46:56 +01:00
control_drought . event ( ) ;
2016-09-01 23:19:00 +02:00
+ + n_control_recv_ ;
2011-12-11 09:28:55 +01:00
}
2023-01-11 20:43:22 +01:00
2011-12-17 11:53:21 +01:00
void copy_progress ( Buffer & buf )
{
if ( progress_ [ 0 ] ) // make sure progress was initialized
std : : memcpy ( buf . data ( ) + 13 , progress_ , 10 ) ;
}
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
void modmsg ( BufferPtr & buf )
{
char * msg = ( char * ) buf - > data ( ) ;
2024-02-22 07:26:46 +01:00
if ( proto_context . is_server ( ) )
2011-12-11 09:28:55 +01:00
{
msg [ 8 ] = ' S ' ;
msg [ 11 ] = ' C ' ;
}
else
{
msg [ 8 ] = ' C ' ;
msg [ 11 ] = ' S ' ;
}
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// increment embedded number
for ( int i = 22 ; i > = 13 ; i - - )
{
if ( msg [ i ] ! = ' 9 ' )
{
msg [ i ] + + ;
break ;
}
else
msg [ i ] = ' 0 ' ;
}
}
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
Frame : : Ptr frame ;
2016-09-01 23:19:00 +02:00
size_t app_bytes_ = 0 ;
size_t net_bytes_ = 0 ;
size_t data_bytes_ = 0 ;
size_t n_control_send_ = 0 ;
size_t n_control_recv_ = 0 ;
BufferPtr templ ;
2023-06-06 18:31:22 +02:00
# if !FEEDBACK
2016-09-01 23:19:00 +02:00
size_t iteration = 0 ;
2023-06-06 18:31:22 +02:00
# endif
2011-12-11 09:28:55 +01:00
char progress_ [ 11 ] ;
2021-06-12 00:40:59 +02:00
bool disable_xmit_ = false ;
2011-12-11 09:28:55 +01:00
} ;
2014-10-21 04:30:13 +02:00
class TestProtoClient : public TestProto
2011-12-14 17:20:07 +01:00
{
2014-10-21 04:30:13 +02:00
typedef TestProto Base ;
2023-01-11 20:43:22 +01:00
2011-12-14 17:20:07 +01:00
public :
2024-02-22 07:26:46 +01:00
TestProtoClient ( const ProtoContext : : ProtoConfig : : Ptr & config ,
2012-02-04 11:24:54 +01:00
const SessionStats : : Ptr & stats )
2024-02-22 07:26:46 +01:00
: TestProto ( config , stats )
2011-12-14 17:20:07 +01:00
{
}
2023-01-11 20:43:22 +01:00
2011-12-14 17:20:07 +01:00
private :
virtual void client_auth ( Buffer & buf )
{
const std : : string username ( " foo " ) ;
const std : : string password ( " bar " ) ;
2024-02-22 07:26:46 +01:00
ProtoContext : : write_auth_string ( username , buf ) ;
ProtoContext : : write_auth_string ( password , buf ) ;
2011-12-14 17:20:07 +01:00
}
} ;
2014-10-21 04:30:13 +02:00
class TestProtoServer : public TestProto
2011-12-14 17:20:07 +01:00
{
2023-01-11 20:43:22 +01:00
2011-12-14 17:20:07 +01:00
public :
2024-02-22 07:26:46 +01:00
void start ( )
{
proto_context . start ( ) ;
}
2011-12-14 17:20:07 +01:00
OPENVPN_SIMPLE_EXCEPTION ( auth_failed ) ;
2023-01-11 20:43:22 +01:00
2024-02-22 07:26:46 +01:00
TestProtoServer ( const ProtoContext : : ProtoConfig : : Ptr & config ,
2012-02-04 11:24:54 +01:00
const SessionStats : : Ptr & stats )
2024-02-22 07:26:46 +01:00
: TestProto ( config , stats )
2011-12-14 17:20:07 +01:00
{
}
2023-01-11 20:43:22 +01:00
2011-12-14 17:20:07 +01:00
private :
2014-12-21 18:32:37 +01:00
virtual void server_auth ( const std : : string & username ,
const SafeString & password ,
2015-02-01 05:51:25 +01:00
const std : : string & peer_info ,
const AuthCert : : Ptr & auth_cert )
2011-12-14 17:20:07 +01:00
{
# ifdef VERBOSE
std : : cout < < " **** AUTHENTICATE " < < username < < ' / ' < < password < < " PEER INFO: " < < std : : endl ;
std : : cout < < peer_info ;
# endif
if ( username ! = " foo " | | password ! = " bar " )
throw auth_failed ( ) ;
}
} ;
2011-12-13 12:13:27 +01:00
// Simulate a noisy transmission channel where packets can be dropped,
// reordered, or corrupted.
2011-12-11 09:28:55 +01:00
class NoisyWire
{
public :
NoisyWire ( const std : : string title_arg ,
TimePtr now_arg ,
2016-06-29 06:31:17 +02:00
RandomAPI & rand_arg ,
2011-12-11 09:28:55 +01:00
const unsigned int reorder_prob_arg ,
const unsigned int drop_prob_arg ,
const unsigned int corrupt_prob_arg )
: title ( title_arg ) ,
2023-06-06 18:31:22 +02:00
# ifdef VERBOSE
2011-12-11 09:28:55 +01:00
now ( now_arg ) ,
2023-06-06 18:31:22 +02:00
# endif
2011-12-11 09:28:55 +01:00
random ( rand_arg ) ,
reorder_prob ( reorder_prob_arg ) ,
drop_prob ( drop_prob_arg ) ,
corrupt_prob ( corrupt_prob_arg )
{
}
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
template < typename T1 , typename T2 >
void xfer ( T1 & a , T2 & b )
{
2011-12-15 09:48:14 +01:00
// check for errors
2016-09-01 23:19:00 +02:00
a . check_invalidated ( ) ;
b . check_invalidated ( ) ;
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// need to retransmit?
2011-12-15 09:48:14 +01:00
if ( a . do_housekeeping ( ) )
2011-12-11 09:28:55 +01:00
{
# ifdef VERBOSE
2011-12-15 09:48:14 +01:00
std : : cout < < now - > raw ( ) < < " " < < title < < " Housekeeping " < < std : : endl ;
2011-12-11 09:28:55 +01:00
# endif
}
2016-09-01 23:19:00 +02:00
// queue a control channel packet
a . app_send_templ ( ) ;
2011-12-11 09:28:55 +01:00
// queue a data channel packet
2024-02-22 07:26:46 +01:00
if ( a . proto_context . data_channel_ready ( ) )
2011-12-11 09:28:55 +01:00
{
2016-09-01 23:19:00 +02:00
BufferPtr bp = a . data_encrypt_string ( " Waiting for godot A... Waiting for godot B... Waiting for godot C... Waiting for godot D... Waiting for godot E... Waiting for godot F... Waiting for godot G... Waiting for godot H... Waiting for godot I... Waiting for godot J... " ) ;
2011-12-11 09:28:55 +01:00
wire . push_back ( bp ) ;
}
// transfer network packets from A -> wire
while ( ! a . net_out . empty ( ) )
{
BufferPtr bp = a . net_out . front ( ) ;
# ifdef VERBOSE
std : : cout < < now - > raw ( ) < < " " < < title < < " " < < a . dump_packet ( * bp ) < < std : : endl ;
# endif
a . net_out . pop_front ( ) ;
wire . push_back ( bp ) ;
}
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// transfer network packets from wire -> B
while ( true )
{
BufferPtr bp = recv ( ) ;
if ( ! bp )
break ;
2024-02-22 07:26:46 +01:00
typename ProtoContext : : PacketType pt = b . proto_context . packet_type ( * bp ) ;
2011-12-11 09:28:55 +01:00
if ( pt . is_control ( ) )
2011-12-13 05:46:56 +01:00
{
# ifdef VERBOSE
if ( ! b . control_net_validate ( pt , * bp ) ) // not strictly necessary since control_net_recv will also validate
std : : cout < < now - > raw ( ) < < " " < < title < < " CONTROL PACKET VALIDATION FAILED " < < std : : endl ;
# endif
2024-02-22 07:26:46 +01:00
b . proto_context . control_net_recv ( pt , std : : move ( bp ) ) ;
2011-12-13 05:46:56 +01:00
}
2011-12-11 09:28:55 +01:00
else if ( pt . is_data ( ) )
{
try
{
b . data_decrypt ( pt , * bp ) ;
# ifdef VERBOSE
if ( bp - > size ( ) )
{
2016-09-01 23:19:00 +02:00
const std : : string show ( ( char * ) bp - > data ( ) , std : : min ( bp - > size ( ) , size_t ( 40 ) ) ) ;
2011-12-13 05:46:56 +01:00
std : : cout < < now - > raw ( ) < < " " < < title < < " DATA CHANNEL DECRYPT: " < < show < < std : : endl ;
2011-12-11 09:28:55 +01:00
}
# endif
}
2023-08-11 13:20:12 +02:00
catch ( [[maybe_unused]] const std : : exception & e )
2011-12-11 09:28:55 +01:00
{
# ifdef VERBOSE
std : : cout < < now - > raw ( ) < < " " < < title < < " Exception on data channel decrypt: " < < e . what ( ) < < std : : endl ;
# endif
}
}
2016-09-01 23:19:00 +02:00
else
{
# ifdef VERBOSE
std : : cout < < now - > raw ( ) < < " " < < title < < " KEY_STATE_ERROR " < < std : : endl ;
# endif
2024-02-22 07:26:46 +01:00
b . proto_context . stat ( ) . error ( Error : : KEY_STATE_ERROR ) ;
2016-09-01 23:19:00 +02:00
}
2021-06-12 00:40:59 +02:00
# ifdef SIMULATE_UDP_AMPLIFY_ATTACK
2024-02-22 07:26:46 +01:00
if ( b . proto_context . is_state_client_wait_reset_ack ( ) )
2021-06-12 00:40:59 +02:00
{
b . disable_xmit ( ) ;
# ifdef VERBOSE
std : : cout < < now - > raw ( ) < < " " < < title < < " SIMULATE_UDP_AMPLIFY_ATTACK disable client xmit " < < std : : endl ;
# endif
}
# endif
2023-01-11 20:43:22 +01:00
}
2024-02-22 07:26:46 +01:00
b . proto_context . flush ( true ) ;
2023-01-11 20:43:22 +01:00
}
2021-06-12 00:40:59 +02:00
2011-12-11 09:28:55 +01:00
private :
BufferPtr recv ( )
{
2014-10-21 04:30:13 +02:00
# ifdef SIMULATE_OOO
2011-12-11 09:28:55 +01:00
// simulate packets being received out of order
if ( wire . size ( ) > = 2 & & ! rand ( reorder_prob ) )
{
const size_t i = random . randrange ( wire . size ( ) - 1 ) + 1 ;
# ifdef VERBOSE
std : : cout < < now - > raw ( ) < < " " < < title < < " Simulating packet reordering " < < i < < " -> 0 " < < std : : endl ;
# endif
std : : swap ( wire [ 0 ] , wire [ i ] ) ;
}
2014-10-21 04:30:13 +02:00
# endif
2011-12-11 09:28:55 +01:00
if ( wire . size ( ) )
{
BufferPtr bp = wire . front ( ) ;
wire . pop_front ( ) ;
# ifdef VERBOSE
std : : cout < < now - > raw ( ) < < " " < < title < < " Received packet, size= " < < bp - > size ( ) < < std : : endl ;
# endif
2014-10-21 04:30:13 +02:00
# ifdef SIMULATE_DROPPED
2011-12-11 09:28:55 +01:00
// simulate dropped packet
if ( ! rand ( drop_prob ) )
{
# ifdef VERBOSE
std : : cout < < now - > raw ( ) < < " " < < title < < " Simulating a dropped packet " < < std : : endl ;
# endif
return BufferPtr ( ) ;
}
2014-10-21 04:30:13 +02:00
# endif
2011-12-11 09:28:55 +01:00
2014-10-21 04:30:13 +02:00
# ifdef SIMULATE_CORRUPTED
2011-12-11 09:28:55 +01:00
// simulate corrupted packet
2011-12-13 05:46:56 +01:00
if ( bp - > size ( ) & & ! rand ( corrupt_prob ) )
2011-12-11 09:28:55 +01:00
{
# ifdef VERBOSE
std : : cout < < now - > raw ( ) < < " " < < title < < " Simulating a corrupted packet " < < std : : endl ;
# endif
const size_t pos = random . randrange ( bp - > size ( ) ) ;
2023-09-29 16:09:01 +02:00
const unsigned char value = random . randrange ( std : : numeric_limits < unsigned char > : : max ( ) ) ;
2011-12-11 09:28:55 +01:00
( * bp ) [ pos ] = value ;
}
2014-10-21 04:30:13 +02:00
# endif
2011-12-11 09:28:55 +01:00
return bp ;
}
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
return BufferPtr ( ) ;
}
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
unsigned int rand ( const unsigned int prob )
{
if ( prob )
return random . randrange ( prob ) ;
else
return 1 ;
}
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
std : : string title ;
2023-06-06 18:31:22 +02:00
# ifdef VERBOSE
2011-12-11 09:28:55 +01:00
TimePtr now ;
2023-06-06 18:31:22 +02:00
# endif
2016-06-29 06:31:17 +02:00
RandomAPI & random ;
2011-12-11 09:28:55 +01:00
unsigned int reorder_prob ;
unsigned int drop_prob ;
unsigned int corrupt_prob ;
std : : deque < BufferPtr > wire ;
} ;
2012-02-04 11:24:54 +01:00
class MySessionStats : public SessionStats
{
public :
2015-05-18 05:26:53 +02:00
typedef RCPtr < MySessionStats > Ptr ;
2023-01-11 20:43:22 +01:00
2012-02-04 11:24:54 +01:00
MySessionStats ( )
{
std : : memset ( errors , 0 , sizeof ( errors ) ) ;
}
2023-01-11 20:43:22 +01:00
2015-05-17 10:53:37 +02:00
virtual void error ( const size_t err_type , const std : : string * text = nullptr )
2012-02-04 11:24:54 +01:00
{
if ( err_type < Error : : N_ERRORS )
+ + errors [ err_type ] ;
}
2023-01-11 20:43:22 +01:00
2012-02-04 11:24:54 +01:00
count_t get_error_count ( const Error : : Type type ) const
{
if ( type < Error : : N_ERRORS )
return errors [ type ] ;
else
return 0 ;
}
2023-01-11 20:43:22 +01:00
2014-12-21 18:32:37 +01:00
void show_error_counts ( ) const
{
for ( size_t i = 0 ; i < Error : : N_ERRORS ; + + i )
{
count_t c = errors [ i ] ;
if ( c )
std : : cerr < < Error : : name ( i ) < < " : " < < c < < std : : endl ;
}
}
2023-01-11 20:43:22 +01:00
2012-02-04 11:24:54 +01:00
private :
count_t errors [ Error : : N_ERRORS ] ;
} ;
2011-12-13 12:13:27 +01:00
// execute the unit test in one thread
2024-02-07 18:30:43 +01:00
int test ( const int thread_num , bool use_tls_ekm )
2011-12-11 09:28:55 +01:00
{
try
{
// frame
2020-02-18 18:34:45 +01:00
Frame : : Ptr frame ( new Frame ( Frame : : Context ( 128 , 378 , 128 , 0 , 16 , 0 ) ) ) ;
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// RNG
2023-11-22 03:53:27 +01:00
ClientRandomAPI : : Ptr rng_cli ( new ClientRandomAPI ( ) ) ;
ClientRandomAPI : : Ptr prng_cli ( new ClientRandomAPI ( ) ) ;
ServerRandomAPI : : Ptr rng_serv ( new ServerRandomAPI ( ) ) ;
ServerRandomAPI : : Ptr prng_serv ( new ServerRandomAPI ( ) ) ;
2016-06-29 06:31:17 +02:00
MTRand rng_noncrypto ;
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// init simulated time
Time time ;
const Time : : Duration time_step = Time : : Duration : : binary_ms ( 100 ) ;
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// client config files
2023-06-13 17:47:41 +02:00
const std : : string ca_crt = read_text ( TEST_KEYCERT_DIR " ca.crt " ) ;
const std : : string client_crt = read_text ( TEST_KEYCERT_DIR " client.crt " ) ;
const std : : string client_key = read_text ( TEST_KEYCERT_DIR " client.key " ) ;
const std : : string server_crt = read_text ( TEST_KEYCERT_DIR " server.crt " ) ;
const std : : string server_key = read_text ( TEST_KEYCERT_DIR " server.key " ) ;
const std : : string dh_pem = read_text ( TEST_KEYCERT_DIR " dh.pem " ) ;
const std : : string tls_auth_key = read_text ( TEST_KEYCERT_DIR " tls-auth.key " ) ;
const std : : string tls_crypt_v2_server_key = read_text ( TEST_KEYCERT_DIR " tls-crypt-v2-server.key " ) ;
const std : : string tls_crypt_v2_client_key = read_text ( TEST_KEYCERT_DIR " tls-crypt-v2-client.key " ) ;
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// client config
2015-02-01 05:51:25 +01:00
ClientSSLAPI : : Config : : Ptr cc ( new ClientSSLAPI : : Config ( ) ) ;
cc - > set_mode ( Mode ( Mode : : CLIENT ) ) ;
cc - > set_frame ( frame ) ;
2024-02-05 13:12:20 +01:00
cc - > set_rng ( rng_cli ) ;
2011-12-11 09:28:55 +01:00
# ifdef USE_APPLE_SSL
2015-02-01 05:51:25 +01:00
cc - > load_identity ( " etest " ) ;
2011-12-11 09:28:55 +01:00
# else
2015-02-01 05:51:25 +01:00
cc - > load_ca ( ca_crt , true ) ;
cc - > load_cert ( client_crt ) ;
cc - > load_private_key ( client_key ) ;
2011-12-11 09:28:55 +01:00
# endif
2015-02-01 05:51:25 +01:00
cc - > set_tls_version_min ( TLS_VER_MIN ) ;
2011-12-11 09:28:55 +01:00
# ifdef VERBOSE
2015-02-01 05:51:25 +01:00
cc - > set_debug_level ( 1 ) ;
2012-03-14 01:51:40 +01:00
# endif
2023-01-11 20:43:22 +01:00
2014-12-31 02:15:05 +01:00
// stats
2012-02-04 11:24:54 +01:00
MySessionStats : : Ptr cli_stats ( new MySessionStats ) ;
2014-12-31 02:15:05 +01:00
MySessionStats : : Ptr serv_stats ( new MySessionStats ) ;
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// client ProtoContext config
2014-10-21 04:30:13 +02:00
typedef ProtoContext ClientProtoContext ;
2023-07-18 10:58:25 +02:00
ClientProtoContext : : ProtoConfig : : Ptr cp ( new ClientProtoContext : : ProtoConfig ) ;
2015-02-01 05:51:25 +01:00
cp - > ssl_factory = cc - > new_factory ( ) ;
2021-12-20 15:32:45 +01:00
CryptoAlgs : : allow_default_dc_algs < ClientCryptoAPI > ( cp - > ssl_factory - > libctx ( ) , false , false ) ;
2021-10-12 18:55:29 +02:00
cp - > dc . set_factory ( new CryptoDCSelect < ClientCryptoAPI > ( cp - > ssl_factory - > libctx ( ) , frame , cli_stats , prng_cli ) ) ;
2014-10-21 04:30:13 +02:00
cp - > tlsprf_factory . reset ( new CryptoTLSPRFFactory < ClientCryptoAPI > ( ) ) ;
2011-12-11 09:28:55 +01:00
cp - > frame = frame ;
cp - > now = & time ;
2012-03-12 13:24:40 +01:00
cp - > rng = rng_cli ;
cp - > prng = prng_cli ;
2011-12-14 12:34:33 +01:00
cp - > protocol = Protocol ( Protocol : : UDPv4 ) ;
cp - > layer = Layer ( Layer : : OSI_LAYER_3 ) ;
2014-12-21 18:32:37 +01:00
# ifdef PROTOv2
cp - > enable_op32 = true ;
cp - > remote_peer_id = 100 ;
# endif
cp - > comp_ctx = CompressContext ( COMP_METH , false ) ;
2016-09-01 23:19:00 +02:00
cp - > dc . set_cipher ( CryptoAlgs : : lookup ( PROTO_CIPHER ) ) ;
cp - > dc . set_digest ( CryptoAlgs : : lookup ( PROTO_DIGEST ) ) ;
2024-02-07 18:30:43 +01:00
if ( use_tls_ekm )
cp - > dc . set_key_derivation ( CryptoAlgs : : KeyDerivation : : TLS_EKM ) ;
2011-12-13 05:46:56 +01:00
# ifdef USE_TLS_AUTH
2014-10-21 04:30:13 +02:00
cp - > tls_auth_factory . reset ( new CryptoOvpnHMACFactory < ClientCryptoAPI > ( ) ) ;
2017-03-24 10:00:39 +01:00
cp - > tls_key . parse ( tls_auth_key ) ;
2016-09-01 23:19:00 +02:00
cp - > set_tls_auth_digest ( CryptoAlgs : : lookup ( PROTO_DIGEST ) ) ;
2013-01-30 17:24:37 +01:00
cp - > key_direction = 0 ;
2017-03-24 10:00:39 +01:00
# endif
# ifdef USE_TLS_CRYPT
cp - > tls_crypt_factory . reset ( new CryptoTLSCryptFactory < ClientCryptoAPI > ( ) ) ;
cp - > tls_key . parse ( tls_auth_key ) ;
2023-01-25 10:18:04 +01:00
cp - > set_tls_crypt_algs ( ) ;
2023-01-25 10:26:40 +01:00
cp - > tls_crypt_ = ClientProtoContext : : Config : : TLSCrypt : : V1 ;
2017-06-30 05:13:22 +02:00
# endif
# ifdef USE_TLS_CRYPT_V2
cp - > tls_crypt_factory . reset ( new CryptoTLSCryptFactory < ClientCryptoAPI > ( ) ) ;
2023-01-25 10:18:04 +01:00
cp - > set_tls_crypt_algs ( ) ;
2017-06-30 17:07:10 +02:00
{
TLSCryptV2ClientKey tls_crypt_v2_key ( cp - > tls_crypt_context ) ;
tls_crypt_v2_key . parse ( tls_crypt_v2_client_key ) ;
tls_crypt_v2_key . extract_key ( cp - > tls_key ) ;
tls_crypt_v2_key . extract_wkc ( cp - > wkc ) ;
}
2023-07-18 10:58:25 +02:00
cp - > tls_crypt_ = ClientProtoContext : : ProtoConfig : : TLSCrypt : : V2 ;
2011-12-13 05:46:56 +01:00
# endif
2011-12-11 09:28:55 +01:00
cp - > pid_mode = PacketIDReceive : : UDP_MODE ;
2012-08-31 23:39:01 +02:00
# if defined(HANDSHAKE_WINDOW)
cp - > handshake_window = Time : : Duration : : seconds ( HANDSHAKE_WINDOW ) ;
# elif SITER > 1
2011-12-17 11:53:21 +01:00
cp - > handshake_window = Time : : Duration : : seconds ( 30 ) ;
# else
2011-12-15 09:48:14 +01:00
cp - > handshake_window = Time : : Duration : : seconds ( 18 ) ; // will cause a small number of handshake failures
2011-12-17 11:53:21 +01:00
# endif
2016-09-01 23:19:00 +02:00
# ifdef BECOME_PRIMARY_CLIENT
cp - > become_primary = Time : : Duration : : seconds ( BECOME_PRIMARY_CLIENT ) ;
# else
cp - > become_primary = cp - > handshake_window ;
# endif
cp - > tls_timeout = Time : : Duration : : milliseconds ( TLS_TIMEOUT_CLIENT ) ;
2012-09-15 08:56:18 +02:00
# if defined(CLIENT_NO_RENEG)
cp - > renegotiate = Time : : Duration : : infinite ( ) ;
# else
2014-03-03 22:43:38 +01:00
cp - > renegotiate = Time : : Duration : : seconds ( RENEG ) ;
2012-09-15 08:56:18 +02:00
# endif
cp - > expire = cp - > renegotiate + cp - > renegotiate ;
2011-12-15 09:48:14 +01:00
cp - > keepalive_ping = Time : : Duration : : seconds ( 5 ) ;
cp - > keepalive_timeout = Time : : Duration : : seconds ( 60 ) ;
2021-06-12 00:40:59 +02:00
cp - > keepalive_timeout_early = cp - > keepalive_timeout ;
2011-12-11 09:28:55 +01:00
2011-12-14 12:34:33 +01:00
# ifdef VERBOSE
std : : cout < < " CLIENT OPTIONS: " < < cp - > options_string ( ) < < std : : endl ;
std : : cout < < " CLIENT PEER INFO: " < < std : : endl ;
std : : cout < < cp - > peer_info_string ( ) ;
# endif
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// server config
2015-02-01 05:51:25 +01:00
ClientSSLAPI : : Config : : Ptr sc ( new ClientSSLAPI : : Config ( ) ) ;
sc - > set_mode ( Mode ( Mode : : SERVER ) ) ;
sc - > set_frame ( frame ) ;
2024-02-05 13:12:20 +01:00
sc - > set_rng ( rng_serv ) ;
2015-02-01 05:51:25 +01:00
sc - > load_ca ( ca_crt , true ) ;
sc - > load_cert ( server_crt ) ;
sc - > load_private_key ( server_key ) ;
sc - > load_dh ( dh_pem ) ;
sc - > set_tls_version_min ( TLS_VER_MIN ) ;
2011-12-11 09:28:55 +01:00
# ifdef VERBOSE
2015-02-01 05:51:25 +01:00
sc - > set_debug_level ( 1 ) ;
2011-12-11 09:28:55 +01:00
# endif
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
// server ProtoContext config
2014-10-21 04:30:13 +02:00
typedef ProtoContext ServerProtoContext ;
2023-07-18 10:58:25 +02:00
ServerProtoContext : : ProtoConfig : : Ptr sp ( new ServerProtoContext : : ProtoConfig ) ;
2015-02-01 05:51:25 +01:00
sp - > ssl_factory = sc - > new_factory ( ) ;
2021-10-11 14:55:59 +02:00
sp - > dc . set_factory ( new CryptoDCSelect < ServerCryptoAPI > ( sp - > ssl_factory - > libctx ( ) , frame , serv_stats , prng_serv ) ) ;
2014-10-21 04:30:13 +02:00
sp - > tlsprf_factory . reset ( new CryptoTLSPRFFactory < ServerCryptoAPI > ( ) ) ;
2011-12-11 09:28:55 +01:00
sp - > frame = frame ;
sp - > now = & time ;
2012-03-12 13:24:40 +01:00
sp - > rng = rng_serv ;
sp - > prng = prng_serv ;
2011-12-14 12:34:33 +01:00
sp - > protocol = Protocol ( Protocol : : UDPv4 ) ;
sp - > layer = Layer ( Layer : : OSI_LAYER_3 ) ;
2014-12-21 18:32:37 +01:00
# ifdef PROTOv2
sp - > enable_op32 = true ;
sp - > remote_peer_id = 101 ;
# endif
sp - > comp_ctx = CompressContext ( COMP_METH , false ) ;
2016-09-01 23:19:00 +02:00
sp - > dc . set_cipher ( CryptoAlgs : : lookup ( PROTO_CIPHER ) ) ;
sp - > dc . set_digest ( CryptoAlgs : : lookup ( PROTO_DIGEST ) ) ;
2024-02-07 18:30:43 +01:00
if ( use_tls_ekm )
sp - > dc . set_key_derivation ( CryptoAlgs : : KeyDerivation : : TLS_EKM ) ;
2011-12-13 05:46:56 +01:00
# ifdef USE_TLS_AUTH
2014-10-21 04:30:13 +02:00
sp - > tls_auth_factory . reset ( new CryptoOvpnHMACFactory < ServerCryptoAPI > ( ) ) ;
2017-03-24 10:00:39 +01:00
sp - > tls_key . parse ( tls_auth_key ) ;
2016-09-01 23:19:00 +02:00
sp - > set_tls_auth_digest ( CryptoAlgs : : lookup ( PROTO_DIGEST ) ) ;
2013-01-30 17:24:37 +01:00
sp - > key_direction = 1 ;
2017-03-24 10:00:39 +01:00
# endif
2017-06-30 17:07:10 +02:00
# if defined(USE_TLS_CRYPT)
2017-06-30 05:13:22 +02:00
sp - > tls_crypt_factory . reset ( new CryptoTLSCryptFactory < ClientCryptoAPI > ( ) ) ;
2017-03-24 10:00:39 +01:00
sp - > tls_key . parse ( tls_auth_key ) ;
2023-01-25 10:18:04 +01:00
sp - > set_tls_crypt_algs ( ) ;
2023-01-25 10:26:40 +01:00
cp - > tls_crypt_ = ClientProtoContext : : Config : : TLSCrypt : : V1 ;
2017-06-30 05:13:22 +02:00
# endif
# ifdef USE_TLS_CRYPT_V2
2017-06-30 17:07:10 +02:00
sp - > tls_crypt_factory . reset ( new CryptoTLSCryptFactory < ClientCryptoAPI > ( ) ) ;
{
TLSCryptV2ServerKey tls_crypt_v2_key ;
tls_crypt_v2_key . parse ( tls_crypt_v2_server_key ) ;
tls_crypt_v2_key . extract_key ( sp - > tls_key ) ;
}
2023-01-25 10:18:04 +01:00
sp - > set_tls_crypt_algs ( ) ;
2017-06-30 17:07:10 +02:00
sp - > tls_crypt_metadata_factory . reset ( new CryptoTLSCryptMetadataFactory ( ) ) ;
2023-07-18 10:58:25 +02:00
sp - > tls_crypt_ = ClientProtoContext : : ProtoConfig : : TLSCrypt : : V2 ;
2011-12-13 05:46:56 +01:00
# endif
2011-12-11 09:28:55 +01:00
sp - > pid_mode = PacketIDReceive : : UDP_MODE ;
2012-08-31 23:39:01 +02:00
# if defined(HANDSHAKE_WINDOW)
sp - > handshake_window = Time : : Duration : : seconds ( HANDSHAKE_WINDOW ) ;
# elif SITER > 1
2011-12-17 11:53:21 +01:00
sp - > handshake_window = Time : : Duration : : seconds ( 30 ) ;
# else
2011-12-15 09:48:14 +01:00
sp - > handshake_window = Time : : Duration : : seconds ( 17 ) + Time : : Duration : : binary_ms ( 512 ) ;
2011-12-17 11:53:21 +01:00
# endif
2016-09-01 23:19:00 +02:00
# ifdef BECOME_PRIMARY_SERVER
sp - > become_primary = Time : : Duration : : seconds ( BECOME_PRIMARY_SERVER ) ;
# else
sp - > become_primary = sp - > handshake_window ;
# endif
sp - > tls_timeout = Time : : Duration : : milliseconds ( TLS_TIMEOUT_SERVER ) ;
2012-09-15 08:56:18 +02:00
# if defined(SERVER_NO_RENEG)
sp - > renegotiate = Time : : Duration : : infinite ( ) ;
# else
2016-05-06 22:13:09 +02:00
// NOTE: if we don't add sp->handshake_window, both client and server reneg-sec (RENEG)
// will be equal and will therefore occasionally collide. Such collisions can sometimes
// produce this OpenSSL error:
// OpenSSLContext::SSL::read_cleartext: BIO_read failed, cap=400 status=-1: error:140E0197:SSL routines:SSL_shutdown:shutdown while in init
// The issue was introduced by this patch in OpenSSL:
// https://github.com/openssl/openssl/commit/64193c8218540499984cd63cda41f3cd491f3f59
sp - > renegotiate = Time : : Duration : : seconds ( RENEG ) + sp - > handshake_window ;
2012-09-15 08:56:18 +02:00
# endif
sp - > expire = sp - > renegotiate + sp - > renegotiate ;
2011-12-15 09:48:14 +01:00
sp - > keepalive_ping = Time : : Duration : : seconds ( 5 ) ;
sp - > keepalive_timeout = Time : : Duration : : seconds ( 60 ) ;
2021-06-12 00:40:59 +02:00
sp - > keepalive_timeout_early = Time : : Duration : : seconds ( 10 ) ;
2011-12-11 09:28:55 +01:00
2011-12-14 12:34:33 +01:00
# ifdef VERBOSE
std : : cout < < " SERVER OPTIONS: " < < sp - > options_string ( ) < < std : : endl ;
std : : cout < < " SERVER PEER INFO: " < < std : : endl ;
std : : cout < < sp - > peer_info_string ( ) ;
# endif
2014-10-21 04:30:13 +02:00
TestProtoClient cli_proto ( cp , cli_stats ) ;
TestProtoServer serv_proto ( sp , serv_stats ) ;
2011-12-11 09:28:55 +01:00
2011-12-17 11:53:21 +01:00
for ( int i = 0 ; i < SITER ; + + i )
2011-12-11 09:28:55 +01:00
{
2011-12-17 11:53:21 +01:00
# ifdef VERBOSE
std : : cout < < " ***** SITER " < < i < < std : : endl ;
# endif
cli_proto . reset ( ) ;
serv_proto . reset ( ) ;
2016-06-29 06:31:17 +02:00
NoisyWire client_to_server ( " Client -> Server " , & time , rng_noncrypto , 8 , 16 , 32 ) ; // last value: 32
NoisyWire server_to_client ( " Server -> Client " , & time , rng_noncrypto , 8 , 16 , 32 ) ; // last value: 32
2011-12-17 11:53:21 +01:00
2012-03-14 04:24:45 +01:00
int j = - 1 ;
try
{
2016-09-01 23:19:00 +02:00
# if FEEDBACK
2012-03-14 04:24:45 +01:00
// start feedback loop
cli_proto . initial_app_send ( message ) ;
serv_proto . start ( ) ;
2016-09-01 23:19:00 +02:00
# else
cli_proto . app_send_templ_init ( message ) ;
serv_proto . app_send_templ_init ( message ) ;
# endif
2023-01-11 20:43:22 +01:00
2012-03-14 04:24:45 +01:00
// message loop
for ( j = 0 ; j < ITER ; + + j )
{
client_to_server . xfer ( cli_proto , serv_proto ) ;
server_to_client . xfer ( serv_proto , cli_proto ) ;
time + = time_step ;
}
}
catch ( const std : : exception & e )
2011-12-17 11:53:21 +01:00
{
2012-03-14 04:24:45 +01:00
std : : cerr < < " Exception[ " < < i < < ' / ' < < j < < " ]: " < < e . what ( ) < < std : : endl ;
2012-08-31 08:50:43 +02:00
return 1 ;
2011-12-17 11:53:21 +01:00
}
2011-12-11 09:28:55 +01:00
}
2023-01-11 20:43:22 +01:00
2011-12-13 05:46:56 +01:00
cli_proto . finalize ( ) ;
serv_proto . finalize ( ) ;
2023-01-11 20:43:22 +01:00
2011-12-11 09:28:55 +01:00
const size_t ab = cli_proto . app_bytes ( ) + serv_proto . app_bytes ( ) ;
const size_t nb = cli_proto . net_bytes ( ) + serv_proto . net_bytes ( ) ;
const size_t db = cli_proto . data_bytes ( ) + serv_proto . data_bytes ( ) ;
2023-01-11 20:43:22 +01:00
2012-08-31 08:50:43 +02:00
std : : cerr < < " *** app bytes= " < < ab
2011-12-13 05:46:56 +01:00
< < " net_bytes= " < < nb
< < " data_bytes= " < < db
< < " prog= " < < cli_proto . progress ( ) < < ' / ' < < serv_proto . progress ( )
2016-09-01 23:19:00 +02:00
# if !FEEDBACK
< < " CTRL= " < < cli_proto . n_control_recv ( ) < < ' / ' < < cli_proto . n_control_send ( ) < < ' / ' < < serv_proto . n_control_recv ( ) < < ' / ' < < serv_proto . n_control_send ( )
# endif
2011-12-13 05:46:56 +01:00
< < " D= " < < cli_proto . control_drought ( ) . raw ( ) < < ' / ' < < cli_proto . data_drought ( ) . raw ( ) < < ' / ' < < serv_proto . control_drought ( ) . raw ( ) < < ' / ' < < serv_proto . data_drought ( ) . raw ( )
2024-02-22 07:26:46 +01:00
< < " N= " < < cli_proto . proto_context . negotiations ( ) < < ' / ' < < serv_proto . proto_context . negotiations ( )
< < " SH= " < < cli_proto . proto_context . slowest_handshake ( ) . raw ( ) < < ' / ' < < serv_proto . proto_context . slowest_handshake ( ) . raw ( )
2012-02-04 11:24:54 +01:00
< < " HE= " < < cli_stats - > get_error_count ( Error : : HANDSHAKE_TIMEOUT ) < < ' / ' < < serv_stats - > get_error_count ( Error : : HANDSHAKE_TIMEOUT )
2011-12-13 05:46:56 +01:00
< < std : : endl ;
2014-12-21 18:32:37 +01:00
# ifdef STATS
std : : cerr < < " -------- CLIENT STATS -------- " < < std : : endl ;
cli_stats - > show_error_counts ( ) ;
std : : cerr < < " -------- SERVER STATS -------- " < < std : : endl ;
serv_stats - > show_error_counts ( ) ;
2016-09-01 23:19:00 +02:00
# endif
# ifdef OPENVPN_MAX_DATALIMIT_BYTES
std : : cerr < < " ------------------------------ " < < std : : endl ;
std : : cerr < < " MAX_DATALIMIT_BYTES= " < < DataLimit : : max_bytes ( ) < < std : : endl ;
2014-12-21 18:32:37 +01:00
# endif
2011-12-11 09:28:55 +01:00
}
2012-02-17 20:28:44 +01:00
catch ( const std : : exception & e )
2011-12-11 09:28:55 +01:00
{
std : : cerr < < " Exception: " < < e . what ( ) < < std : : endl ;
2012-08-31 08:50:43 +02:00
return 1 ;
2011-12-11 09:28:55 +01:00
}
2012-08-31 08:50:43 +02:00
return 0 ;
2011-12-13 05:46:56 +01:00
}
2024-02-07 18:30:43 +01:00
int test_retry ( const int thread_num , const int n_retries , bool use_tls_ekm )
2021-06-01 07:21:30 +02:00
{
int ret = 1 ;
for ( int i = 0 ; i < n_retries ; + + i )
{
2024-02-07 18:30:43 +01:00
ret = test ( thread_num , use_tls_ekm ) ;
2021-06-01 07:21:30 +02:00
if ( ! ret )
return 0 ;
std : : cout < < " Retry " < < ( i + 1 ) < < ' / ' < < n_retries < < std : : endl ;
}
std : : cout < < " Failed " < < std : : endl ;
return ret ;
}
2024-02-07 18:30:43 +01:00
class ProtoUnitTest : public testing : : Test
2011-12-13 05:46:56 +01:00
{
2024-02-07 18:30:43 +01:00
// Sets up the test fixture.
virtual void SetUp ( )
{
# if defined(USE_MBEDTLS)
mbedtls_debug_set_threshold ( 1 ) ;
# endif
openvpn : : Compress : : set_log_level ( 0 ) ;
2014-03-05 01:42:00 +01:00
2024-02-07 18:30:43 +01:00
# ifdef PROTO_VERBOSE
openvpn : : ProtoContext : : set_log_level ( 2 ) ;
# else
openvpn : : ProtoContext : : set_log_level ( 0 ) ;
# endif
}
// Tears down the test fixture.
virtual void TearDown ( )
{
2017-02-24 00:59:51 +01:00
# if defined(USE_MBEDTLS)
2024-02-07 18:30:43 +01:00
mbedtls_debug_set_threshold ( 4 ) ;
2014-12-31 02:15:05 +01:00
# endif
2024-02-07 18:30:43 +01:00
openvpn : : Compress : : set_log_level ( openvpn : : Compress : : default_log_level ) ;
openvpn : : ProtoContext : : set_log_level ( openvpn : : ProtoContext : : default_log_level ) ;
}
} ;
2014-12-31 02:15:05 +01:00
2024-02-07 18:30:43 +01:00
TEST_F ( ProtoUnitTest , base_single_thread_tls_ekm )
{
if ( ! openvpn : : SSLLib : : SSLAPI : : support_key_material_export ( ) )
GTEST_SKIP_ ( " our mbed TLS implementation does not support TLS EKM " ) ;
int ret = 0 ;
ret = test_retry ( 1 , N_RETRIES , true ) ;
EXPECT_EQ ( ret , 0 ) ;
}
TEST_F ( ProtoUnitTest , base_single_thread_no_tls_ekm )
{
int ret = 0 ;
ret = test_retry ( 1 , N_RETRIES , false ) ;
EXPECT_EQ ( ret , 0 ) ;
}
TEST_F ( ProtoUnitTest , base_multiple_thread )
{
unsigned int num_threads = std : : thread : : hardware_concurrency ( ) ;
# if defined(PROTO_N_THREADS) && PROTO_N_THREADS >= 1
2024-04-19 16:27:18 +02:00
num_threads = PROTO_N_THREADS ;
2024-02-07 18:30:43 +01:00
# endif
std : : vector < std : : thread > running_threads { } ;
std : : vector < int > results ( num_threads , - 777 ) ;
for ( unsigned int i = 0 ; i < num_threads ; + + i )
2011-12-13 05:46:56 +01:00
{
2024-02-07 18:30:43 +01:00
running_threads . emplace_back ( [ i , & results ] ( )
{
/* Use ekm on odd threads */
const bool use_ekm = openvpn : : SSLLib : : SSLAPI : : support_key_material_export ( ) & & ( i % 2 = = 0 ) ;
results [ i ] = test_retry ( static_cast < int > ( i ) , N_RETRIES , use_ekm ) ; } ) ;
2011-12-13 05:46:56 +01:00
}
2024-02-07 18:30:43 +01:00
for ( unsigned int i = 0 ; i < num_threads ; + + i )
2011-12-13 05:46:56 +01:00
{
2024-02-07 18:30:43 +01:00
running_threads [ i ] . join ( ) ;
2011-12-13 05:46:56 +01:00
}
2017-09-04 13:18:16 +02:00
2024-02-07 18:30:43 +01:00
// expect 1 for all threads
const std : : vector < int > expected_results ( num_threads , 0 ) ;
EXPECT_THAT ( expected_results , : : testing : : ContainerEq ( results ) ) ;
2011-12-11 09:28:55 +01:00
}
2024-03-20 03:50:34 +01:00
TEST ( proto , iv_ciphers_aead )
{
CryptoAlgs : : allow_default_dc_algs < SSLLib : : CryptoAPI > ( nullptr , true , false ) ;
auto protoConf = openvpn : : ProtoContext : : ProtoConfig ( ) ;
auto infostring = protoConf . peer_info_string ( ) ;
auto ivciphers = infostring . substr ( infostring . find ( " IV_CIPHERS= " ) ) ;
ivciphers = ivciphers . substr ( 0 , ivciphers . find ( " \n " ) ) ;
std : : string expectedstr { " IV_CIPHERS=AES-128-GCM:AES-192-GCM:AES-256-GCM " } ;
if ( SSLLib : : CryptoAPI : : CipherContextAEAD : : is_supported ( nullptr , openvpn : : CryptoAlgs : : CHACHA20_POLY1305 ) )
expectedstr + = " :CHACHA20-POLY1305 " ;
EXPECT_EQ ( ivciphers , expectedstr ) ;
}
TEST ( proto , iv_ciphers_non_preferred )
{
CryptoAlgs : : allow_default_dc_algs < SSLLib : : CryptoAPI > ( nullptr , false , false ) ;
auto protoConf = openvpn : : ProtoContext : : ProtoConfig ( ) ;
auto infostring = protoConf . peer_info_string ( ) ;
auto ivciphers = infostring . substr ( infostring . find ( " IV_CIPHERS= " ) ) ;
ivciphers = ivciphers . substr ( 0 , ivciphers . find ( " \n " ) ) ;
std : : string expectedstr { " IV_CIPHERS=AES-128-CBC:AES-192-CBC:AES-256-CBC:AES-128-GCM:AES-192-GCM:AES-256-GCM " } ;
if ( SSLLib : : CryptoAPI : : CipherContextAEAD : : is_supported ( nullptr , openvpn : : CryptoAlgs : : CHACHA20_POLY1305 ) )
expectedstr + = " :CHACHA20-POLY1305 " ;
EXPECT_EQ ( ivciphers , expectedstr ) ;
}
TEST ( proto , iv_ciphers_legacy )
{
/* Need to a whole lot of things to enable legacy provider/OpenSSL context */
SSLLib : : SSLAPI : : Config : : Ptr config = new SSLLib : : SSLAPI : : Config ;
EXPECT_TRUE ( config ) ;
StrongRandomAPI : : Ptr rng ( new SSLLib : : RandomAPI ( ) ) ;
config - > set_rng ( rng ) ;
config - > set_mode ( Mode ( Mode : : CLIENT ) ) ;
config - > set_flags ( SSLConfigAPI : : LF_ALLOW_CLIENT_CERT_NOT_REQUIRED ) ;
config - > set_local_cert_enabled ( false ) ;
config - > enable_legacy_algorithms ( true ) ;
auto factory_client = config - > new_factory ( ) ;
EXPECT_TRUE ( factory_client ) ;
auto client = factory_client - > ssl ( ) ;
auto libctx = factory_client - > libctx ( ) ;
CryptoAlgs : : allow_default_dc_algs < SSLLib : : CryptoAPI > ( libctx , false , true ) ;
auto protoConf = openvpn : : ProtoContext : : ProtoConfig ( ) ;
auto infostring = protoConf . peer_info_string ( ) ;
auto ivciphers = infostring . substr ( infostring . find ( " IV_CIPHERS= " ) ) ;
ivciphers = ivciphers . substr ( 0 , ivciphers . find ( " \n " ) ) ;
2024-04-30 16:48:00 +02:00
std : : string expectedstr { " IV_CIPHERS=none:AES-128-CBC:AES-192-CBC:AES-256-CBC:DES-CBC:DES-EDE3-CBC:BF-CBC:AES-128-GCM:AES-192-GCM:AES-256-GCM " } ;
2024-03-20 03:50:34 +01:00
if ( SSLLib : : CryptoAPI : : CipherContextAEAD : : is_supported ( nullptr , openvpn : : CryptoAlgs : : CHACHA20_POLY1305 ) )
expectedstr + = " :CHACHA20-POLY1305 " ;
EXPECT_EQ ( ivciphers , expectedstr ) ;
}