28#include <gmock/gmock.h>
36#if !defined(USE_TLS_AUTH) && !defined(USE_TLS_CRYPT)
39#define USE_TLS_CRYPT_V2
47#define PROTO_CIPHER "BF-CBC"
48#define TLS_VER_MIN TLSVersion::UNDEF
49#define HANDSHAKE_WINDOW 60
50#define BECOME_PRIMARY_CLIENT 5
51#define BECOME_PRIMARY_SERVER 5
52#define TLS_TIMEOUT_CLIENT 1000
53#define TLS_TIMEOUT_SERVER 1000
56#define PROTO_CIPHER "BF-CBC"
57#define TLS_VER_MIN TLSVersion::UNDEF
58#define HANDSHAKE_WINDOW 10
59#define BECOME_PRIMARY_CLIENT 10
60#define BECOME_PRIMARY_SERVER 10
61#define TLS_TIMEOUT_CLIENT 2000
62#define TLS_TIMEOUT_SERVER 1000
65#define PROTO_CIPHER "BF-CBC"
66#define TLS_VER_MIN TLSVersion::UNDEF
67#define HANDSHAKE_WINDOW 60
68#define BECOME_PRIMARY_CLIENT 60
69#define BECOME_PRIMARY_SERVER 10
70#define TLS_TIMEOUT_CLIENT 2000
71#define TLS_TIMEOUT_SERVER 1000
74#error unknown BF value
78#ifndef TLS_TIMEOUT_CLIENT
79#define TLS_TIMEOUT_CLIENT 2000
81#ifndef TLS_TIMEOUT_SERVER
82#define TLS_TIMEOUT_SERVER 2000
88#define SIMULATE_DROPPED
89#define SIMULATE_CORRUPTED
94#define RENEG PROTO_RENEG
108#define ITER PROTO_ITER
115#define SITER PROTO_SITER
131#if !defined(PROTO_VERBOSE) && !defined(QUIET) && ITER <= 10000
135#define STRINGIZE1(x) #x
136#define STRINGIZE(x) STRINGIZE1(x)
141#define PROTO_CIPHER "AES-256-GCM"
142#define TLS_VER_MIN TLSVersion::Type::V1_2
144#define PROTO_CIPHER "AES-128-CBC"
145#define TLS_VER_MIN TLSVersion::Type::UNDEF
151#define PROTO_DIGEST "SHA1"
157#define COMP_METH CompressContext::LZ4v2
159#define COMP_METH CompressContext::COMP_STUBv2
162#define COMP_METH CompressContext::LZO_STUB
176#if !(defined(USE_OPENSSL) || defined(USE_MBEDTLS))
177#error Must define one or more of USE_OPENSSL, USE_MBEDTLS.
180#if defined(USE_OPENSSL) && defined(USE_MBEDTLS)
182#define USE_OPENSSL_SERVER
183#elif !defined(USE_OPENSSL) && defined(USE_MBEDTLS)
184#define USE_MBEDTLS_SERVER
185#elif defined(USE_OPENSSL) && !defined(USE_MBEDTLS)
186#define USE_OPENSSL_SERVER
188#error no server setup
191#if defined(USE_OPENSSL) || defined(USE_OPENSSL_SERVER)
197#if defined(USE_MBEDTLS) || defined(USE_MBEDTLS_SERVER)
201#include <mbedtls/debug.h>
209#ifdef USE_MBEDTLS_SERVER
213#elif defined(USE_OPENSSL_SERVER)
218#error No server SSL implementation defined
226#elif defined(USE_OPENSSL)
231#error No client SSL implementation defined
234const char message[] =
"Message _->_ 0000000000 It was a bright cold day in April, and the clocks\n"
235 "were striking thirteen. Winston Smith, his chin nuzzled\n"
236 "into his breast in an effort to escape the vile wind,\n"
237 "slipped quickly through the glass doors of Victory\n"
238 "Mansions, though not quickly enough to prevent a\n"
239 "swirl of gritty dust from entering along with him.\n"
241 "It was a bright cold day in April, and the clocks\n"
242 "were striking thirteen. Winston Smith, his chin nuzzled\n"
243 "into his breast in an effort to escape the vile wind,\n"
244 "slipped quickly through the glass doors of Victory\n"
245 "Mansions, though not quickly enough to prevent a\n"
246 "swirl of gritty dust from entering along with him.\n"
247 "It was a bright cold day in April, and the clocks\n"
248 "were striking thirteen. Winston Smith, his chin nuzzled\n"
249 "into his breast in an effort to escape the vile wind,\n"
250 "slipped quickly through the glass doors of Victory\n"
251 "Mansions, though not quickly enough to prevent a\n"
252 "swirl of gritty dust from entering along with him.\n"
253 "It was a bright cold day in April, and the clocks\n"
254 "were striking thirteen. Winston Smith, his chin nuzzled\n"
255 "into his breast in an effort to escape the vile wind,\n"
256 "slipped quickly through the glass doors of Victory\n"
257 "Mansions, though not quickly enough to prevent a\n"
258 "swirl of gritty dust from entering along with him.\n"
259 "It was a bright cold day in April, and the clocks\n"
260 "were striking thirteen. Winston Smith, his chin nuzzled\n"
261 "into his breast in an effort to escape the vile wind,\n"
262 "slipped quickly through the glass doors of Victory\n"
263 "Mansions, though not quickly enough to prevent a\n"
264 "swirl of gritty dust from entering along with him.\n"
289#if defined(VERBOSE) || defined(DROUGHT_LIMIT)
293 std::cout <<
"*** Drought " <<
name <<
" has reached " << r <<
"\n";
296 if (r > DROUGHT_LIMIT)
297 throw drought_limit_exceeded();
357 const size_t msglen = std::strlen(
msg) + 1;
367 const size_t msglen = std::strlen(
msg) + 1;
375 if (
bool(iteration++ & 1) == is_server())
412 bp->write((
unsigned char *)str, std::strlen(str));
498 std::cerr <<
"no CONTROL_WKC_V1 packet was emitted by the client\n";
505 std::cerr <<
"CONTROL_WKC_V1 packet too large: " << size
506 <<
" > " << max_size <<
'\n';
533 if (
work->size() >= 23)
538 const ssize_t trunc = 64;
539 const std::string show((
char *)
work->data(), trunc);
540 std::cout << now().raw() <<
" " << mode().str() <<
" " << show <<
"\n";
559 char *
msg = (
char *)buf->data();
572 for (
int i = 22; i >= 13; i--)
591 size_t iteration = 0;
611 const std::string username(
"foo");
612 const std::string password(
"bar");
639 const std::string &peer_info,
643 std::cout <<
"**** AUTHENTICATE " << username <<
'/' << password <<
" PEER INFO:\n";
644 std::cout << peer_info;
646 if (username !=
"foo" || password !=
"bar")
659 const unsigned int reorder_prob_arg,
660 const unsigned int drop_prob_arg,
661 const unsigned int corrupt_prob_arg)
673 template <
typename T1,
typename T2>
677 a.check_invalidated();
678 b.check_invalidated();
681 if (a.do_housekeeping())
684 std::cout << now->raw() <<
" " <<
title <<
" Housekeeping\n";
692 if (a.proto_context.data_channel_ready())
694 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...");
699 while (!a.net_out.empty())
703 std::cout << now->raw() <<
" " <<
title <<
" " << a.dump_packet(*bp) <<
"\n";
705 a.net_out.pop_front();
719 if (!b.control_net_validate(pt, *bp))
720 std::cout << now->raw() <<
" " <<
title <<
" CONTROL PACKET VALIDATION FAILED\n";
722 b.proto_context.control_net_recv(pt, std::move(bp));
728 b.data_decrypt(pt, *bp);
732 const std::string show((
char *)bp->data(), std::min(bp->size(),
size_t(40)));
733 std::cout << now->raw() <<
" " <<
title <<
" DATA CHANNEL DECRYPT: " << show <<
"\n";
737 catch ([[maybe_unused]]
const std::exception &e)
740 std::cout << now->raw() <<
" " <<
title <<
" Exception on data channel decrypt: " << e.what() <<
"\n";
747 std::cout << now->raw() <<
" " <<
title <<
" KEY_STATE_ERROR\n";
752#ifdef SIMULATE_UDP_AMPLIFY_ATTACK
753 if (b.proto_context.is_state_client_wait_reset_ack())
757 std::cout << now->raw() <<
" " <<
title <<
" SIMULATE_UDP_AMPLIFY_ATTACK disable client xmit\n";
762 b.proto_context.flush(
true);
774 std::cout << now->raw() <<
" " <<
title <<
" Simulating packet reordering " << i <<
" -> 0\n";
786 std::cout << now->raw() <<
" " <<
title <<
" Received packet, size=" << bp->size() <<
"\n";
789#ifdef SIMULATE_DROPPED
794 std::cout << now->raw() <<
" " <<
title <<
" Simulating a dropped packet\n";
800#ifdef SIMULATE_CORRUPTED
805 std::cout << now->raw() <<
" " <<
title <<
" Simulating a corrupted packet\n";
808 const unsigned char value =
random.
randrange(std::numeric_limits<unsigned char>::max());
818 unsigned int rand(
const unsigned int prob)
846 void error(
const size_t err_type,
const std::string *text =
nullptr)
override
879 const std::string client_crt =
read_text(TEST_KEYCERT_DIR
"client.crt");
880 const std::string client_key =
read_text(TEST_KEYCERT_DIR
"client.key");
881 const std::string ca_crt =
read_text(TEST_KEYCERT_DIR
"ca.crt");
884 ClientSSLAPI::Config::Ptr cc(
new ClientSSLAPI::Config());
886 cc->set_frame(frame);
888 cc->load_ca(ca_crt,
true);
889 cc->load_cert(client_crt);
890 cc->load_private_key(client_key);
891 if (tls_version_mismatch)
892 cc->set_tls_version_max(TLSVersion::Type::V1_2);
896 cc->set_debug_level(1);
903 ClientRandomAPI::Ptr rng,
906 const std::string &tls_crypt_v2_key_fn =
"",
907 bool tls_auth_only =
false,
908 bool use_dynamic_tls_crypt =
false)
910 const std::string tls_auth_key =
read_text(TEST_KEYCERT_DIR
"tls-auth.key");
911 const std::string tls_crypt_v2_client_key = tls_crypt_v2_key_fn.empty()
912 ?
read_text(TEST_KEYCERT_DIR
"tls-crypt-v2-client.key")
913 :
read_text(TEST_KEYCERT_DIR + tls_crypt_v2_key_fn);
917 ClientProtoContext::ProtoConfig::Ptr cp(
new ClientProtoContext::ProtoConfig);
918 cp->ssl_factory = cc->new_factory();
919 CryptoAlgs::allow_default_dc_algs<ClientCryptoAPI>(cp->ssl_factory->libctx(),
false,
false);
922 cp->frame = std::move(frame);
929 cp->enable_op32 =
true;
930 cp->remote_peer_id = 100;
938 cp->tls_auth_key.parse(tls_auth_key);
940 cp->key_direction = 0;
944 cp->tls_crypt_key.parse(tls_auth_key);
945 cp->set_tls_crypt_algs();
946 cp->tls_crypt_ = ProtoContext::ProtoConfig::TLSCrypt::V1;
948#ifdef USE_TLS_CRYPT_V2
954 cp->tls_auth_key.parse(tls_auth_key);
956 cp->key_direction = 0;
961 cp->set_tls_crypt_algs();
964 tls_crypt_v2_key.
parse(tls_crypt_v2_client_key);
968 cp->tls_crypt_ = ProtoContext::ProtoConfig::TLSCrypt::V2;
970 if (use_dynamic_tls_crypt)
971 cp->enable_dynamic_tls_crypt();
973#ifdef HANDSHAKE_WINDOW
974 cp->handshake_window = Time::Duration::seconds(HANDSHAKE_WINDOW);
976 cp->handshake_window = Time::Duration::seconds(30);
978 cp->handshake_window = Time::Duration::seconds(18);
980#ifdef BECOME_PRIMARY_CLIENT
981 cp->become_primary = Time::Duration::seconds(BECOME_PRIMARY_CLIENT);
983 cp->become_primary = cp->handshake_window;
986#ifdef CLIENT_NO_RENEG
989 cp->renegotiate = Time::Duration::seconds(
RENEG);
991 cp->expire = cp->renegotiate + cp->renegotiate;
992 cp->keepalive_ping = Time::Duration::seconds(5);
993 cp->keepalive_timeout = Time::Duration::seconds(60);
994 cp->keepalive_timeout_early = cp->keepalive_timeout;
997 std::cout <<
"CLIENT OPTIONS: " << cp->options_string() <<
"\n";
998 std::cout <<
"CLIENT PEER INFO:\n";
999 std::cout << cp->peer_info_string();
1033 ClientRandomAPI::Ptr prng_cli(
new ClientRandomAPI());
1034 ServerRandomAPI::Ptr prng_serv(
new ServerRandomAPI());
1039 const Time::Duration time_step = Time::Duration::binary_ms(100);
1042 const std::string ca_crt =
read_text(TEST_KEYCERT_DIR
"ca.crt");
1043 const std::string server_crt =
read_text(TEST_KEYCERT_DIR
"server.crt");
1044 const std::string server_key =
read_text(TEST_KEYCERT_DIR
"server.key");
1045 const std::string dh_pem =
read_text(TEST_KEYCERT_DIR
"dh.pem");
1046 const std::string tls_auth_key =
read_text(TEST_KEYCERT_DIR
"tls-auth.key");
1048 ?
read_text(TEST_KEYCERT_DIR
"tls-crypt-v2-server.key")
1057 cp->dc.set_key_derivation(CryptoAlgs::KeyDerivation::TLS_EKM);
1064 ServerSSLAPI::Config::Ptr sc(
new ClientSSLAPI::Config());
1066 sc->set_frame(frame);
1067 sc->set_rng(prng_serv);
1068 sc->load_ca(ca_crt,
true);
1069 sc->load_cert(server_crt);
1070 sc->load_private_key(server_key);
1071 sc->load_dh(dh_pem);
1074 sc->set_debug_level(1);
1079 ServerProtoContext::ProtoConfig::Ptr sp(
new ServerProtoContext::ProtoConfig);
1080 sp->ssl_factory = sc->new_factory();
1085 sp->rng = prng_serv;
1086 sp->prng = prng_serv;
1090 sp->enable_op32 =
true;
1091 sp->remote_peer_id = 101;
1097 sp->dc.set_key_derivation(CryptoAlgs::KeyDerivation::TLS_EKM);
1100 sp->tls_auth_key.parse(tls_auth_key);
1102 sp->key_direction = 1;
1106 sp->tls_crypt_key.parse(tls_auth_key);
1107 sp->set_tls_crypt_algs();
1108 cp->tls_crypt_ = ProtoContext::ProtoConfig::TLSCrypt::V1;
1110#ifdef USE_TLS_CRYPT_V2
1116 tls_crypt_v2_key.
parse(tls_crypt_v2_server_key);
1120 sp->set_tls_crypt_algs();
1122 sp->tls_crypt_ = ProtoContext::ProtoConfig::TLSCrypt::V2;
1124 sp->tls_crypt_v2_serverkey_dir = TEST_KEYCERT_DIR;
1127 sp->enable_dynamic_tls_crypt();
1132 sp->tls_auth_key.parse(tls_auth_key);
1134 sp->key_direction = 1;
1137#ifdef HANDSHAKE_WINDOW
1138 sp->handshake_window = Time::Duration::seconds(HANDSHAKE_WINDOW);
1140 sp->handshake_window = Time::Duration::seconds(30);
1142 sp->handshake_window = Time::Duration::seconds(17) + Time::Duration::binary_ms(512);
1144#ifdef BECOME_PRIMARY_SERVER
1145 sp->become_primary = Time::Duration::seconds(BECOME_PRIMARY_SERVER);
1147 sp->become_primary = sp->handshake_window;
1150#ifdef SERVER_NO_RENEG
1159 sp->renegotiate = Time::Duration::seconds(
RENEG) + sp->handshake_window;
1161 sp->expire = sp->renegotiate + sp->renegotiate;
1162 sp->keepalive_ping = Time::Duration::seconds(5);
1163 sp->keepalive_timeout = Time::Duration::seconds(60);
1164 sp->keepalive_timeout_early = Time::Duration::seconds(10);
1167 std::cout <<
"SERVER OPTIONS: " << sp->options_string() <<
"\n";
1168 std::cout <<
"SERVER PEER INFO:\n";
1169 std::cout << sp->peer_info_string();
1175 for (
int i = 0; i <
SITER; ++i)
1178 std::cout <<
"***** SITER " << i <<
"\n";
1183 NoisyWire client_to_server(
"Client -> Server", &time, rng_noncrypto, 8, 16, 32);
1184 NoisyWire server_to_client(
"Server -> Client", &time, rng_noncrypto, 8, 16, 32);
1209 for (
size_t k = 0; k < 64; ++k)
1210 bp->push_back(
static_cast<unsigned char>(k));
1231 for (j = 0; j <
ITER; ++j)
1233 client_to_server.
xfer(cli_proto, serv_proto);
1234 server_to_client.
xfer(serv_proto, cli_proto);
1250 std::cerr <<
"control packet exceeded mssfix_ctrl: "
1257 catch (
const std::exception &e)
1259 std::cerr <<
"Exception[" << i <<
'/' << j <<
"]: " << e.what() <<
'\n';
1271 std::cerr <<
"*** app bytes=" << ab
1272 <<
" net_bytes=" << nb
1273 <<
" data_bytes=" << db
1291 std::cerr <<
"dynamic tls-crypt: no rekey completed\n";
1297 std::cerr <<
"-------- CLIENT STATS --------\n";
1299 std::cerr <<
"-------- SERVER STATS --------\n";
1302#ifdef OPENVPN_MAX_DATALIMIT_BYTES
1303 std::cerr <<
"------------------------------\n";
1304 std::cerr <<
"MAX_DATALIMIT_BYTES=" << DataLimit::max_bytes() <<
"\n";
1307 catch (
const std::exception &e)
1309 std::cerr <<
"Exception: " << e.what() <<
'\n';
1318 for (
int i = 0; i < n_retries; ++i)
1320 ret =
test(test_config);
1323 std::cout <<
"Retry " << (i + 1) <<
'/' << n_retries <<
'\n';
1325 std::cout <<
"Failed\n";
1335 mbedtls_debug_set_threshold(1);
1351 mbedtls_debug_set_threshold(4);
1360 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1361 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1385 int ret =
test({.tls_version_mismatch =
true});
1390#ifdef USE_TLS_CRYPT_V2
1393 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key"});
1399 int ret =
test({.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-missing-serverkey.key"});
1405 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key", .use_tls_auth_with_tls_crypt_v2 =
true});
1417 {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key",
1418 .use_tls_auth_with_tls_crypt_v2 =
true,
1419 .client_tls_auth_only =
true,
1420 .spoof_hard_reset_v3 =
true});
1433 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1434 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1442 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1443 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1445 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key", .use_dynamic_tls_crypt =
true});
1458 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1459 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1462 {.use_tls_auth_with_tls_crypt_v2 =
true,
1463 .use_dynamic_tls_crypt =
true});
1469 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1470 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1473 {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key",
1474 .use_tls_auth_with_tls_crypt_v2 =
true,
1475 .use_dynamic_tls_crypt =
true});
1487 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key", .force_resend_wkc =
true});
1499 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key", .force_resend_wkc =
true, .control_payload = 278});
1509 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key", .force_resend_wkc =
true, .mssfix_ctrl = 420});
1536 pcfg->set_tls_crypt_algs();
1542 pcfg->tls_crypt_key.parse(
read_text(TEST_KEYCERT_DIR
"tls-auth.key"));
1561 buf.
data()[0] =
static_cast<unsigned char>(11u << 3);
1562 const uint16_t net_wkc_len = htons(wkc_len);
1563 std::memcpy(buf.
data() + size -
sizeof(net_wkc_len), &net_wkc_len,
sizeof(net_wkc_len));
1617 pcfg->tls_crypt_v2_serverkey_id =
true;
1618 pcfg->tls_crypt_v2_serverkey_dir = TEST_KEYCERT_DIR;
1622 const uint16_t wkc_len = min_wkc_len();
1623 BufferAllocated buf = make_wkc_v1_packet(frame_size() + wkc_len, wkc_len);
1638 EXPECT_EQ(buf.
size(), frame_size());
1645 EXPECT_EQ(buf.
size(), 400u);
1653 EXPECT_EQ(buf.
size(), 400u);
1660 BufferAllocated buf = make_wkc_v1_packet(400,
static_cast<uint16_t
>(400 - frame_size() + 1));
1662 EXPECT_EQ(buf.
size(), 400u);
1677 pcfg->tls_crypt_v2_serverkey_id =
true;
1682 BufferAllocated too_small = make_wkc_v1_packet(400, min_wkc_len() - 1);
1687 EXPECT_EQ(ok.
size(), 400u - min_wkc_len());
1693 unsigned int num_threads = std::thread::hardware_concurrency();
1694#if defined(PROTO_N_THREADS) && PROTO_N_THREADS >= 1
1695 num_threads = PROTO_N_THREADS;
1698 std::vector<std::thread> running_threads{};
1699 std::vector<int> results(num_threads, -777);
1701 for (
unsigned int i = 0; i < num_threads; ++i)
1703 running_threads.emplace_back([i, &results]()
1706 const bool use_ekm = openvpn::SSLLib::SSLAPI::support_key_material_export() && (i % 2 == 0);
1709 for (
unsigned int i = 0; i < num_threads; ++i)
1711 running_threads[i].join();
1716 const std::vector<int> expected_results(num_threads, 0);
1718 EXPECT_THAT(expected_results, ::testing::ContainerEq(results));
1723 CryptoAlgs::allow_default_dc_algs<SSLLib::CryptoAPI>(
nullptr,
true,
false);
1727 auto infostring = protoConf.peer_info_string(
false);
1729 auto ivciphers = infostring.substr(infostring.find(
"IV_CIPHERS="));
1730 ivciphers = ivciphers.substr(0, ivciphers.find(
"\n"));
1733 std::string expectedstr{
"IV_CIPHERS=AES-128-GCM:AES-192-GCM:AES-256-GCM"};
1735 expectedstr +=
":CHACHA20-POLY1305";
1737 EXPECT_EQ(ivciphers, expectedstr);
1742 CryptoAlgs::allow_default_dc_algs<SSLLib::CryptoAPI>(
nullptr,
false,
false);
1746 auto infostring = protoConf.peer_info_string(
true);
1748 auto ivciphers = infostring.substr(infostring.find(
"IV_CIPHERS="));
1749 ivciphers = ivciphers.substr(0, ivciphers.find(
"\n"));
1752 std::string expectedstr{
"IV_CIPHERS=AES-128-CBC:AES-192-CBC:AES-256-CBC:AES-128-GCM:AES-192-GCM:AES-256-GCM"};
1754 expectedstr +=
":CHACHA20-POLY1305";
1756 EXPECT_EQ(ivciphers, expectedstr);
1763 SSLLib::SSLAPI::Config::Ptr
config =
new SSLLib::SSLAPI::Config;
1771 config->set_local_cert_enabled(
false);
1772 config->enable_legacy_algorithms(
true);
1774 auto factory_client =
config->new_factory();
1775 EXPECT_TRUE(factory_client);
1777 auto client = factory_client->ssl();
1778 auto libctx = factory_client->libctx();
1781 CryptoAlgs::allow_default_dc_algs<SSLLib::CryptoAPI>(libctx,
false,
true);
1785 auto infostring = protoConf.peer_info_string(
false);
1787 auto ivciphers = infostring.substr(infostring.find(
"IV_CIPHERS="));
1788 ivciphers = ivciphers.substr(0, ivciphers.find(
"\n"));
1792 std::string expectedstr{
"IV_CIPHERS=none:AES-128-CBC:AES-192-CBC:AES-256-CBC:DES-CBC:DES-EDE3-CBC"};
1795 expectedstr +=
":BF-CBC";
1797 expectedstr +=
":AES-128-GCM:AES-192-GCM:AES-256-GCM";
1800 expectedstr +=
":CHACHA20-POLY1305";
1802 EXPECT_EQ(ivciphers, expectedstr);
1805TEST(Proto, ControlmessageInvalidchar)
1807 std::string valid_auth_fail{
"AUTH_FAILED: go away"};
1808 std::string valid_auth_fail_newline_end{
"AUTH_FAILED: go away\n"};
1809 std::string invalid_auth_fail{
"AUTH_FAILED: go\n away\n"};
1810 std::string lot_of_whitespace{
"AUTH_FAILED: a lot of white space\n\n\r\n\r\n\r\n"};
1811 std::string only_whitespace{
"\n\n\r\n\r\n\r\n"};
1812 std::string empty{
""};
1821 auto msg = ProtoContext::read_control_string<std::string>(valid_auth_fail_buf);
1822 EXPECT_EQ(
msg, valid_auth_fail);
1825 auto msg2 = ProtoContext::read_control_string<std::string>(valid_auth_fail_newline_end_buf);
1826 EXPECT_EQ(msg2, valid_auth_fail);
1829 auto msg3 = ProtoContext::read_control_string<std::string>(invalid_auth_fail_buf);
1830 EXPECT_EQ(msg3,
"AUTH_FAILED: go\n away");
1833 auto msg4 = ProtoContext::read_control_string<std::string>(lot_of_whitespace_buf);
1834 EXPECT_EQ(msg4,
"AUTH_FAILED: a lot of white space");
1837 auto msg5 = ProtoContext::read_control_string<std::string>(only_whitespace_buf);
1838 EXPECT_EQ(msg5,
"");
1841 auto msg6 = ProtoContext::read_control_string<std::string>(empty_buf);
1842 EXPECT_EQ(msg6,
"");
1861 std::vector<openvpn::ClientEvent::Base::Ptr>
events;
1866 asio::io_context io_context;
1867 ClientRandomAPI::Ptr rng_cli(
new ClientRandomAPI());
1883 std::move(cli_stats),
1885 clisessconf.cli_events = std::move(eqv_ptr);
1888 clisession->validate_and_post_cc_msg(
"valid message");
1891 EXPECT_TRUE(eqv->
events.empty());
1893 clisession->validate_and_post_cc_msg(
"invalid\nmessage");
1894 EXPECT_EQ(eqv->
events.size(), 1);
1895 auto ev = eqv->
events.back();
1899 EXPECT_EQ(uf->name,
"Invalid chars in control message");
1900 EXPECT_EQ(uf->reason,
"Control channel message with invalid characters not allowed to be send with post_cc_msg");
Time::Duration operator()() const
DroughtMeasure(const std::string &name_arg, TimePtr now_arg)
OPENVPN_SIMPLE_EXCEPTION(drought_limit_exceeded)
void add_event(openvpn::ClientEvent::Base::Ptr event) override
std::vector< openvpn::ClientEvent::Base::Ptr > events
void client_proto_terminate()
count_t errors[Error::N_ERRORS]
void error(const size_t err_type, const std::string *text=nullptr) override
count_t get_error_count(const Error::Type type) const
void show_error_counts() const
std::deque< BufferPtr > wire
unsigned int rand(const unsigned int prob)
unsigned int reorder_prob
NoisyWire(const std::string &title_arg, TimePtr now_arg, RandomAPI &rand_arg, const unsigned int reorder_prob_arg, const unsigned int drop_prob_arg, const unsigned int corrupt_prob_arg)
unsigned int corrupt_prob
TestProtoClient(const ProtoContext::ProtoConfig::Ptr &config, const SessionStats::Ptr &stats)
void client_auth(Buffer &buf) override
void server_auth(const std::string &username, const SafeString &password, const std::string &peer_info, const AuthCert::Ptr &auth_cert) override
TestProtoServer(const ProtoContext::ProtoConfig::Ptr &config, const SessionStats::Ptr &stats)
OPENVPN_SIMPLE_EXCEPTION(auth_failed)
TestProto(const ProtoContext::ProtoConfig::Ptr &config, const SessionStats::Ptr &stats)
void control_recv(BufferPtr &&app_bp) override
DroughtMeasure data_drought
void modmsg(BufferPtr &buf)
bool verify_wkc_packets_fit(size_t max_size) const
void data_decrypt(const ProtoContext::PacketType &type, BufferAllocated &in_out)
void control_send(BufferPtr &&app_bp)
void data_encrypt(BufferAllocated &in_out)
std::vector< size_t > wkc_pkt_sizes_
void initial_app_send(const char *msg)
const char * progress() const
void control_send(BufferAllocated &&app_buf)
ProtoContext proto_context
void active(bool primary) override
Called when KeyContext transitions to ACTIVE state.
size_t n_control_recv() const
DroughtMeasure control_drought
size_t max_ctrl_pkt_size() const
BufferPtr data_encrypt_string(const char *str)
size_t n_control_send() const
OPENVPN_EXCEPTION(session_invalidated)
void app_send_templ_init(const char *msg)
void control_net_send(const Buffer &net_buf) override
size_t max_ctrl_pkt_size_
bool supports_epoch_data() override
size_t data_bytes() const
void copy_progress(Buffer &buf)
std::deque< BufferPtr > net_out
size_t frame_size() const
Smallest tls-crypt frame a WKc can follow, from the code under test.
BufferAllocated make_wkc_v1_packet(size_t size, uint16_t wkc_len)
ProtoContext::ProtoConfig::Ptr pcfg
TLSCryptInstance::Ptr tls_crypt_server
uint16_t min_wkc_len() const
const T * c_data() const
Returns a const pointer to the start of the buffer.
size_t size() const
Returns the size of the buffer in T objects.
T * data()
Get a mutable pointer to the start of the array.
bool empty() const
Returns true if the buffer is empty.
void set_size(const size_t size)
After an external method, operating on the array as a mutable unsigned char buffer,...
size_t prepare(const unsigned int context, Buffer &buf) const
static bool strip_resent_wkc(Buffer &recv, const ProtoConfig &proto_config)
Virtually remove a resent WKc from the end of a CONTROL_WKC_V1 packet.
static size_t tls_crypt_frame_size(const ProtoConfig &proto_config)
Smallest tls-crypt frame a WKc can be appended to.
static Error::Type unwrap_tls_crypt_wkc(Buffer &recv, const ProtoConfig &proto_config, TLSCryptInstance &tls_crypt_server, UnwrappedWkc &unwrapped)
Extract and process the TLS crypt WKc information.
static size_t wkc_overhead(const ProtoConfig &proto_config)
What a WKc holds besides the client key and the metadata.
bool control_net_recv(const PacketType &type, BufferPtr &&net_bp)
const Time::Duration & slowest_handshake()
void flush(const bool control_channel)
void control_send(BufferPtr &&app_bp)
PacketType packet_type(const Buffer &buf)
void data_encrypt(BufferAllocated &in_out)
@ CONTROL_HARD_RESET_CLIENT_V3
static unsigned char op_compose(const unsigned int opcode, const unsigned int key_id)
static void write_auth_string(const S &str, Buffer &buf)
bool data_decrypt(const PacketType &type, BufferAllocated &in_out)
Error::Type invalidation_reason() const
unsigned int negotiations() const
Time next_housekeeping() const
void reset(const ProtoSessionID cookie_psid=ProtoSessionID())
Resets ProtoContext *this to it's initial state.
void start(const ProtoSessionID cookie_psid=ProtoSessionID())
Initialize the state machine and start protocol negotiation.
const ProtoConfig & conf() const
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
void swap(RCPtr &rhs) noexcept
swaps the contents of two RCPtr<T>
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
Abstract base class for random number generators.
T randrange(const T end)
Return a uniformly distributed random number in the range [0, end)
static Ptr Create(ArgsT &&...args)
Creates a new instance of RcEnable with the given arguments.
@ LF_ALLOW_CLIENT_CERT_NOT_REQUIRED
A string-like type that clears the buffer contents on delete.
virtual void init(SSLLib::Ctx libctx, const StaticKey &key_hmac, const StaticKey &key_crypt)=0
void parse(const std::string &key_text)
void extract_wkc(BufferAllocated &wkc_out) const
void extract_key(OpenVPNStaticKey &tls_key)
void extract_key(OpenVPNStaticKey &tls_key)
void parse(const std::string &key_text)
static TimeType infinite()
static constexpr int default_log_level
static void set_log_level(int level)
set the log level for all loggigng
void work(openvpn_io::io_context &io_context, ThreadCommon &tc, MyRunContext &runctx, const unsigned int unit)
constexpr BufferFlags GROW(1U<< 2)
if enabled, buffer will grow (otherwise buffer_full exception will be thrown)
constexpr BufferFlags CONSTRUCT_ZERO(1U<< 0)
if enabled, constructors/init will zero allocated space
constexpr BufferFlags NO_FLAGS(0U)
no flags set
Type lookup(const std::string &name)
const char * name(const size_t type)
bool is_valid_utf8(const STRING &str, const size_t max_len_flags=0)
std::string read_text(const std::string &filename, const std::uint64_t max_size=0)
RCPtr< BufferAllocatedRc > BufferPtr
ProtoContext::ProtoConfig::Ptr proto_context_config
What a WKc yields, owned by whoever asked for the unwrap.
OpenVPNStaticKey client_key
Kc, the client key the WKc wrapped.
const std::string & tls_crypt_v2_key_fn
bool client_tls_auth_only
bool tls_version_mismatch
bool use_tls_auth_with_tls_crypt_v2
bool use_dynamic_tls_crypt
static const char config[]
#define TLS_TIMEOUT_CLIENT
#define TLS_TIMEOUT_SERVER
static auto create_client_proto_context(ClientSSLAPI::Config::Ptr cc, Frame::Ptr frame, ClientRandomAPI::Ptr rng, MySessionStats::Ptr cli_stats, Time &time, const std::string &tls_crypt_v2_key_fn="", bool tls_auth_only=false, bool use_dynamic_tls_crypt=false)
int test_retry(const int n_retries, const struct proto_test &test_config)
TEST_F(ProtoUnitTest, BaseSingleThreadTlsEkm)
TEST(Proto, IvCiphersAead)
static auto create_client_ssl_config(Frame::Ptr frame, ClientRandomAPI::Ptr rng, bool tls_version_mismatch=false)