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
179#if !(defined(USE_OPENSSL) || defined(USE_MBEDTLS))
180#error Must define one or more of USE_OPENSSL, USE_MBEDTLS.
183#if defined(USE_OPENSSL) && defined(USE_MBEDTLS)
185#define USE_OPENSSL_SERVER
186#elif !defined(USE_OPENSSL) && defined(USE_MBEDTLS)
187#define USE_MBEDTLS_SERVER
188#elif defined(USE_OPENSSL) && !defined(USE_MBEDTLS)
189#define USE_OPENSSL_SERVER
191#error no server setup
194#if defined(USE_OPENSSL) || defined(USE_OPENSSL_SERVER)
200#if defined(USE_MBEDTLS) || defined(USE_MBEDTLS_SERVER)
204#include <mbedtls/debug.h>
212#ifdef USE_MBEDTLS_SERVER
216#elif defined(USE_OPENSSL_SERVER)
221#error No server SSL implementation defined
229#elif defined(USE_OPENSSL)
234#error No client SSL implementation defined
237const char message[] =
"Message _->_ 0000000000 It was a bright cold day in April, and the clocks\n"
238 "were striking thirteen. Winston Smith, his chin nuzzled\n"
239 "into his breast in an effort to escape the vile wind,\n"
240 "slipped quickly through the glass doors of Victory\n"
241 "Mansions, though not quickly enough to prevent a\n"
242 "swirl of gritty dust from entering along with him.\n"
244 "It was a bright cold day in April, and the clocks\n"
245 "were striking thirteen. Winston Smith, his chin nuzzled\n"
246 "into his breast in an effort to escape the vile wind,\n"
247 "slipped quickly through the glass doors of Victory\n"
248 "Mansions, though not quickly enough to prevent a\n"
249 "swirl of gritty dust from entering along with him.\n"
250 "It was a bright cold day in April, and the clocks\n"
251 "were striking thirteen. Winston Smith, his chin nuzzled\n"
252 "into his breast in an effort to escape the vile wind,\n"
253 "slipped quickly through the glass doors of Victory\n"
254 "Mansions, though not quickly enough to prevent a\n"
255 "swirl of gritty dust from entering along with him.\n"
256 "It was a bright cold day in April, and the clocks\n"
257 "were striking thirteen. Winston Smith, his chin nuzzled\n"
258 "into his breast in an effort to escape the vile wind,\n"
259 "slipped quickly through the glass doors of Victory\n"
260 "Mansions, though not quickly enough to prevent a\n"
261 "swirl of gritty dust from entering along with him.\n"
262 "It was a bright cold day in April, and the clocks\n"
263 "were striking thirteen. Winston Smith, his chin nuzzled\n"
264 "into his breast in an effort to escape the vile wind,\n"
265 "slipped quickly through the glass doors of Victory\n"
266 "Mansions, though not quickly enough to prevent a\n"
267 "swirl of gritty dust from entering along with him.\n"
292#if defined(VERBOSE) || defined(DROUGHT_LIMIT)
296 std::cout <<
"*** Drought " <<
name <<
" has reached " << r <<
"\n";
299 if (r > DROUGHT_LIMIT)
300 throw drought_limit_exceeded();
360 const size_t msglen = std::strlen(
msg) + 1;
370 const size_t msglen = std::strlen(
msg) + 1;
378 if (
bool(iteration++ & 1) == is_server())
415 bp->write((
unsigned char *)str, std::strlen(str));
501 std::cerr <<
"no CONTROL_WKC_V1 packet was emitted by the client\n";
508 std::cerr <<
"CONTROL_WKC_V1 packet too large: " << size
509 <<
" > " << max_size <<
'\n';
536 if (
work->size() >= 23)
541 const ssize_t trunc = 64;
542 const std::string show((
char *)
work->data(), trunc);
543 std::cout << now().raw() <<
" " << mode().str() <<
" " << show <<
"\n";
562 char *
msg = (
char *)buf->data();
575 for (
int i = 22; i >= 13; i--)
594 size_t iteration = 0;
614 const std::string username(
"foo");
615 const std::string password(
"bar");
642 const std::string &peer_info,
646 std::cout <<
"**** AUTHENTICATE " << username <<
'/' << password <<
" PEER INFO:\n";
647 std::cout << peer_info;
649 if (username !=
"foo" || password !=
"bar")
662 const unsigned int reorder_prob_arg,
663 const unsigned int drop_prob_arg,
664 const unsigned int corrupt_prob_arg)
676 template <
typename T1,
typename T2>
680 a.check_invalidated();
681 b.check_invalidated();
684 if (a.do_housekeeping())
687 std::cout << now->raw() <<
" " <<
title <<
" Housekeeping\n";
695 if (a.proto_context.data_channel_ready())
697 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...");
702 while (!a.net_out.empty())
706 std::cout << now->raw() <<
" " <<
title <<
" " << a.dump_packet(*bp) <<
"\n";
708 a.net_out.pop_front();
722 if (!b.control_net_validate(pt, *bp))
723 std::cout << now->raw() <<
" " <<
title <<
" CONTROL PACKET VALIDATION FAILED\n";
725 b.proto_context.control_net_recv(pt, std::move(bp));
731 b.data_decrypt(pt, *bp);
735 const std::string show((
char *)bp->data(), std::min(bp->size(),
size_t(40)));
736 std::cout << now->raw() <<
" " <<
title <<
" DATA CHANNEL DECRYPT: " << show <<
"\n";
740 catch ([[maybe_unused]]
const std::exception &e)
743 std::cout << now->raw() <<
" " <<
title <<
" Exception on data channel decrypt: " << e.what() <<
"\n";
750 std::cout << now->raw() <<
" " <<
title <<
" KEY_STATE_ERROR\n";
755#ifdef SIMULATE_UDP_AMPLIFY_ATTACK
756 if (b.proto_context.is_state_client_wait_reset_ack())
760 std::cout << now->raw() <<
" " <<
title <<
" SIMULATE_UDP_AMPLIFY_ATTACK disable client xmit\n";
765 b.proto_context.flush(
true);
777 std::cout << now->raw() <<
" " <<
title <<
" Simulating packet reordering " << i <<
" -> 0\n";
789 std::cout << now->raw() <<
" " <<
title <<
" Received packet, size=" << bp->size() <<
"\n";
792#ifdef SIMULATE_DROPPED
797 std::cout << now->raw() <<
" " <<
title <<
" Simulating a dropped packet\n";
803#ifdef SIMULATE_CORRUPTED
808 std::cout << now->raw() <<
" " <<
title <<
" Simulating a corrupted packet\n";
811 const unsigned char value =
random.
randrange(std::numeric_limits<unsigned char>::max());
821 unsigned int rand(
const unsigned int prob)
849 void error(
const size_t err_type,
const std::string *text =
nullptr)
override
882 const std::string client_crt =
read_text(TEST_KEYCERT_DIR
"client.crt");
883 const std::string client_key =
read_text(TEST_KEYCERT_DIR
"client.key");
884 const std::string ca_crt =
read_text(TEST_KEYCERT_DIR
"ca.crt");
887 ClientSSLAPI::Config::Ptr cc(
new ClientSSLAPI::Config());
889 cc->set_frame(frame);
891 cc->load_ca(ca_crt,
true);
892 cc->load_cert(client_crt);
893 cc->load_private_key(client_key);
894 if (tls_version_mismatch)
895 cc->set_tls_version_max(TLSVersion::Type::V1_2);
899 cc->set_debug_level(1);
906 ClientRandomAPI::Ptr rng,
909 const std::string &tls_crypt_v2_key_fn =
"",
910 bool tls_auth_only =
false,
911 bool use_dynamic_tls_crypt =
false,
912 const std::string &tls_crypt_v2_dir = TEST_KEYCERT_DIR)
914 const std::string tls_auth_key =
read_text(TEST_KEYCERT_DIR
"tls-auth.key");
915 const std::string tls_crypt_v2_client_key = tls_crypt_v2_key_fn.empty()
916 ?
read_text(TEST_KEYCERT_DIR
"tls-crypt-v2-client.key")
917 :
read_text(tls_crypt_v2_dir + tls_crypt_v2_key_fn);
921 ClientProtoContext::ProtoConfig::Ptr cp(
new ClientProtoContext::ProtoConfig);
922 cp->ssl_factory = cc->new_factory();
923 CryptoAlgs::allow_default_dc_algs<ClientCryptoAPI>(cp->ssl_factory->libctx(),
false,
false);
926 cp->frame = std::move(frame);
933 cp->enable_op32 =
true;
934 cp->remote_peer_id = 100;
942 cp->tls_auth_key.parse(tls_auth_key);
944 cp->key_direction = 0;
948 cp->tls_crypt_key.parse(tls_auth_key);
949 cp->set_tls_crypt_algs();
950 cp->tls_crypt_ = ProtoContext::ProtoConfig::TLSCrypt::V1;
952#ifdef USE_TLS_CRYPT_V2
958 cp->tls_auth_key.parse(tls_auth_key);
960 cp->key_direction = 0;
965 cp->set_tls_crypt_algs();
968 tls_crypt_v2_key.
parse(tls_crypt_v2_client_key);
972 cp->tls_crypt_ = ProtoContext::ProtoConfig::TLSCrypt::V2;
974 if (use_dynamic_tls_crypt)
975 cp->enable_dynamic_tls_crypt();
977#ifdef HANDSHAKE_WINDOW
978 cp->handshake_window = Time::Duration::seconds(HANDSHAKE_WINDOW);
980 cp->handshake_window = Time::Duration::seconds(30);
982 cp->handshake_window = Time::Duration::seconds(18);
984#ifdef BECOME_PRIMARY_CLIENT
985 cp->become_primary = Time::Duration::seconds(BECOME_PRIMARY_CLIENT);
987 cp->become_primary = cp->handshake_window;
990#ifdef CLIENT_NO_RENEG
993 cp->renegotiate = Time::Duration::seconds(
RENEG);
995 cp->expire = cp->renegotiate + cp->renegotiate;
996 cp->keepalive_ping = Time::Duration::seconds(5);
997 cp->keepalive_timeout = Time::Duration::seconds(60);
998 cp->keepalive_timeout_early = cp->keepalive_timeout;
1001 std::cout <<
"CLIENT OPTIONS: " << cp->options_string() <<
"\n";
1002 std::cout <<
"CLIENT PEER INFO:\n";
1003 std::cout << cp->peer_info_string();
1040 ClientRandomAPI::Ptr prng_cli(
new ClientRandomAPI());
1041 ServerRandomAPI::Ptr prng_serv(
new ServerRandomAPI());
1046 const Time::Duration time_step = Time::Duration::binary_ms(100);
1049 const std::string ca_crt =
read_text(TEST_KEYCERT_DIR
"ca.crt");
1050 const std::string server_crt =
read_text(TEST_KEYCERT_DIR
"server.crt");
1051 const std::string server_key =
read_text(TEST_KEYCERT_DIR
"server.key");
1052 const std::string dh_pem =
read_text(TEST_KEYCERT_DIR
"dh.pem");
1053 const std::string tls_auth_key =
read_text(TEST_KEYCERT_DIR
"tls-auth.key");
1055 ?
read_text(TEST_KEYCERT_DIR
"tls-crypt-v2-server.key")
1064 cp->dc.set_key_derivation(CryptoAlgs::KeyDerivation::TLS_EKM);
1071 ServerSSLAPI::Config::Ptr sc(
new ClientSSLAPI::Config());
1073 sc->set_frame(frame);
1074 sc->set_rng(prng_serv);
1075 sc->load_ca(ca_crt,
true);
1076 sc->load_cert(server_crt);
1077 sc->load_private_key(server_key);
1078 sc->load_dh(dh_pem);
1081 sc->set_debug_level(1);
1086 ServerProtoContext::ProtoConfig::Ptr sp(
new ServerProtoContext::ProtoConfig);
1087 sp->ssl_factory = sc->new_factory();
1092 sp->rng = prng_serv;
1093 sp->prng = prng_serv;
1097 sp->enable_op32 =
true;
1098 sp->remote_peer_id = 101;
1104 sp->dc.set_key_derivation(CryptoAlgs::KeyDerivation::TLS_EKM);
1107 sp->tls_auth_key.parse(tls_auth_key);
1109 sp->key_direction = 1;
1113 sp->tls_crypt_key.parse(tls_auth_key);
1114 sp->set_tls_crypt_algs();
1115 cp->tls_crypt_ = ProtoContext::ProtoConfig::TLSCrypt::V1;
1117#ifdef USE_TLS_CRYPT_V2
1123 tls_crypt_v2_key.
parse(tls_crypt_v2_server_key);
1127 sp->set_tls_crypt_algs();
1129 sp->tls_crypt_ = ProtoContext::ProtoConfig::TLSCrypt::V2;
1134 sp->enable_dynamic_tls_crypt();
1139 sp->tls_auth_key.parse(tls_auth_key);
1141 sp->key_direction = 1;
1144#ifdef HANDSHAKE_WINDOW
1145 sp->handshake_window = Time::Duration::seconds(HANDSHAKE_WINDOW);
1147 sp->handshake_window = Time::Duration::seconds(30);
1149 sp->handshake_window = Time::Duration::seconds(17) + Time::Duration::binary_ms(512);
1151#ifdef BECOME_PRIMARY_SERVER
1152 sp->become_primary = Time::Duration::seconds(BECOME_PRIMARY_SERVER);
1154 sp->become_primary = sp->handshake_window;
1157#ifdef SERVER_NO_RENEG
1166 sp->renegotiate = Time::Duration::seconds(
RENEG) + sp->handshake_window;
1168 sp->expire = sp->renegotiate + sp->renegotiate;
1169 sp->keepalive_ping = Time::Duration::seconds(5);
1170 sp->keepalive_timeout = Time::Duration::seconds(60);
1171 sp->keepalive_timeout_early = Time::Duration::seconds(10);
1174 std::cout <<
"SERVER OPTIONS: " << sp->options_string() <<
"\n";
1175 std::cout <<
"SERVER PEER INFO:\n";
1176 std::cout << sp->peer_info_string();
1182 for (
int i = 0; i <
SITER; ++i)
1185 std::cout <<
"***** SITER " << i <<
"\n";
1190 NoisyWire client_to_server(
"Client -> Server", &time, rng_noncrypto, 8, 16, 32);
1191 NoisyWire server_to_client(
"Server -> Client", &time, rng_noncrypto, 8, 16, 32);
1216 for (
size_t k = 0; k < 64; ++k)
1217 bp->push_back(
static_cast<unsigned char>(k));
1238 for (j = 0; j <
ITER; ++j)
1240 client_to_server.
xfer(cli_proto, serv_proto);
1241 server_to_client.
xfer(serv_proto, cli_proto);
1257 std::cerr <<
"control packet exceeded mssfix_ctrl: "
1264 catch (
const std::exception &e)
1266 std::cerr <<
"Exception[" << i <<
'/' << j <<
"]: " << e.what() <<
'\n';
1278 std::cerr <<
"*** app bytes=" << ab
1279 <<
" net_bytes=" << nb
1280 <<
" data_bytes=" << db
1298 std::cerr <<
"dynamic tls-crypt: no rekey completed\n";
1304 std::cerr <<
"-------- CLIENT STATS --------\n";
1306 std::cerr <<
"-------- SERVER STATS --------\n";
1309#ifdef OPENVPN_MAX_DATALIMIT_BYTES
1310 std::cerr <<
"------------------------------\n";
1311 std::cerr <<
"MAX_DATALIMIT_BYTES=" << DataLimit::max_bytes() <<
"\n";
1314 catch (
const std::exception &e)
1316 std::cerr <<
"Exception: " << e.what() <<
'\n';
1325 for (
int i = 0; i < n_retries; ++i)
1327 ret =
test(test_config);
1330 std::cout <<
"Retry " << (i + 1) <<
'/' << n_retries <<
'\n';
1332 std::cout <<
"Failed\n";
1342 mbedtls_debug_set_threshold(1);
1358 mbedtls_debug_set_threshold(4);
1367 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1368 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1392 int ret =
test({.tls_version_mismatch =
true});
1397#ifdef USE_TLS_CRYPT_V2
1400 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key"});
1406 int ret =
test({.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-missing-serverkey.key"});
1412 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});
1425 const std::string &client_fn,
1426 const std::uint32_t k_id,
1427 const std::string &metadata)
1429 ServerRandomAPI::Ptr rng(
new ServerRandomAPI());
1437 const std::string key_dir = dir + k_id_hex.substr(0, 2);
1438 std::filesystem::create_directories(key_dir);
1446 client_key.
generate(*rng, server_key, metadata, 0x00, k_id);
1457 const std::string dir =
getTempDirPath(
"ovpn3-tls-crypt-v2-generated/");
1458 std::filesystem::remove_all(dir);
1459 std::filesystem::create_directories(dir);
1463 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"client.key", .tls_crypt_v2_dir = dir});
1466 std::filesystem::remove_all(dir);
1473 const std::string dir =
getTempDirPath(
"ovpn3-tls-crypt-v2-generated-ta/");
1474 std::filesystem::remove_all(dir);
1475 std::filesystem::create_directories(dir);
1480 {.tls_crypt_v2_key_fn =
"client.key",
1481 .tls_crypt_v2_dir = dir,
1482 .use_tls_auth_with_tls_crypt_v2 =
true});
1485 std::filesystem::remove_all(dir);
1496 {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key",
1497 .use_tls_auth_with_tls_crypt_v2 =
true,
1498 .client_tls_auth_only =
true,
1499 .spoof_hard_reset_v3 =
true});
1512 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1513 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1521 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1522 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1524 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key", .use_dynamic_tls_crypt =
true});
1537 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1538 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1541 {.use_tls_auth_with_tls_crypt_v2 =
true,
1542 .use_dynamic_tls_crypt =
true});
1548 if (!openvpn::SSLLib::SSLAPI::support_key_material_export())
1549 GTEST_SKIP_(
"our mbed TLS implementation does not support TLS EKM");
1552 {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key",
1553 .use_tls_auth_with_tls_crypt_v2 =
true,
1554 .use_dynamic_tls_crypt =
true});
1566 int ret =
test_retry(
N_RETRIES, {.tls_crypt_v2_key_fn =
"tls-crypt-v2-client-with-serverkey.key", .force_resend_wkc =
true});
1578 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});
1588 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});
1615 pcfg->set_tls_crypt_algs();
1621 pcfg->tls_crypt_key.parse(
read_text(TEST_KEYCERT_DIR
"tls-auth.key"));
1640 buf.
data()[0] =
static_cast<unsigned char>(11u << 3);
1641 const uint16_t net_wkc_len = htons(wkc_len);
1642 std::memcpy(buf.
data() + size -
sizeof(net_wkc_len), &net_wkc_len,
sizeof(net_wkc_len));
1696 pcfg->tls_crypt_v2_serverkey_id =
true;
1697 pcfg->tls_crypt_v2_serverkey_dir = TEST_KEYCERT_DIR;
1701 const uint16_t wkc_len = min_wkc_len();
1702 BufferAllocated buf = make_wkc_v1_packet(frame_size() + wkc_len, wkc_len);
1717 EXPECT_EQ(buf.
size(), frame_size());
1724 EXPECT_EQ(buf.
size(), 400u);
1732 EXPECT_EQ(buf.
size(), 400u);
1739 BufferAllocated buf = make_wkc_v1_packet(400,
static_cast<uint16_t
>(400 - frame_size() + 1));
1741 EXPECT_EQ(buf.
size(), 400u);
1756 pcfg->tls_crypt_v2_serverkey_id =
true;
1761 BufferAllocated too_small = make_wkc_v1_packet(400, min_wkc_len() - 1);
1766 EXPECT_EQ(ok.
size(), 400u - min_wkc_len());
1772 unsigned int num_threads = std::thread::hardware_concurrency();
1773#if defined(PROTO_N_THREADS) && PROTO_N_THREADS >= 1
1774 num_threads = PROTO_N_THREADS;
1777 std::vector<std::thread> running_threads{};
1778 std::vector<int> results(num_threads, -777);
1780 for (
unsigned int i = 0; i < num_threads; ++i)
1782 running_threads.emplace_back([i, &results]()
1785 const bool use_ekm = openvpn::SSLLib::SSLAPI::support_key_material_export() && (i % 2 == 0);
1788 for (
unsigned int i = 0; i < num_threads; ++i)
1790 running_threads[i].join();
1795 const std::vector<int> expected_results(num_threads, 0);
1797 EXPECT_THAT(expected_results, ::testing::ContainerEq(results));
1802 CryptoAlgs::allow_default_dc_algs<SSLLib::CryptoAPI>(
nullptr,
true,
false);
1806 auto infostring = protoConf.peer_info_string(
false);
1808 auto ivciphers = infostring.substr(infostring.find(
"IV_CIPHERS="));
1809 ivciphers = ivciphers.substr(0, ivciphers.find(
"\n"));
1812 std::string expectedstr{
"IV_CIPHERS=AES-128-GCM:AES-192-GCM:AES-256-GCM"};
1814 expectedstr +=
":CHACHA20-POLY1305";
1816 EXPECT_EQ(ivciphers, expectedstr);
1821 CryptoAlgs::allow_default_dc_algs<SSLLib::CryptoAPI>(
nullptr,
false,
false);
1825 auto infostring = protoConf.peer_info_string(
true);
1827 auto ivciphers = infostring.substr(infostring.find(
"IV_CIPHERS="));
1828 ivciphers = ivciphers.substr(0, ivciphers.find(
"\n"));
1831 std::string expectedstr{
"IV_CIPHERS=AES-128-CBC:AES-192-CBC:AES-256-CBC:AES-128-GCM:AES-192-GCM:AES-256-GCM"};
1833 expectedstr +=
":CHACHA20-POLY1305";
1835 EXPECT_EQ(ivciphers, expectedstr);
1842 SSLLib::SSLAPI::Config::Ptr
config =
new SSLLib::SSLAPI::Config;
1850 config->set_local_cert_enabled(
false);
1851 config->enable_legacy_algorithms(
true);
1853 auto factory_client =
config->new_factory();
1854 EXPECT_TRUE(factory_client);
1856 auto client = factory_client->ssl();
1857 auto libctx = factory_client->libctx();
1860 CryptoAlgs::allow_default_dc_algs<SSLLib::CryptoAPI>(libctx,
false,
true);
1864 auto infostring = protoConf.peer_info_string(
false);
1866 auto ivciphers = infostring.substr(infostring.find(
"IV_CIPHERS="));
1867 ivciphers = ivciphers.substr(0, ivciphers.find(
"\n"));
1871 std::string expectedstr{
"IV_CIPHERS=none:AES-128-CBC:AES-192-CBC:AES-256-CBC:DES-CBC:DES-EDE3-CBC"};
1874 expectedstr +=
":BF-CBC";
1876 expectedstr +=
":AES-128-GCM:AES-192-GCM:AES-256-GCM";
1879 expectedstr +=
":CHACHA20-POLY1305";
1881 EXPECT_EQ(ivciphers, expectedstr);
1884TEST(Proto, ControlmessageInvalidchar)
1886 std::string valid_auth_fail{
"AUTH_FAILED: go away"};
1887 std::string valid_auth_fail_newline_end{
"AUTH_FAILED: go away\n"};
1888 std::string invalid_auth_fail{
"AUTH_FAILED: go\n away\n"};
1889 std::string lot_of_whitespace{
"AUTH_FAILED: a lot of white space\n\n\r\n\r\n\r\n"};
1890 std::string only_whitespace{
"\n\n\r\n\r\n\r\n"};
1891 std::string empty{
""};
1900 auto msg = ProtoContext::read_control_string<std::string>(valid_auth_fail_buf);
1901 EXPECT_EQ(
msg, valid_auth_fail);
1904 auto msg2 = ProtoContext::read_control_string<std::string>(valid_auth_fail_newline_end_buf);
1905 EXPECT_EQ(msg2, valid_auth_fail);
1908 auto msg3 = ProtoContext::read_control_string<std::string>(invalid_auth_fail_buf);
1909 EXPECT_EQ(msg3,
"AUTH_FAILED: go\n away");
1912 auto msg4 = ProtoContext::read_control_string<std::string>(lot_of_whitespace_buf);
1913 EXPECT_EQ(msg4,
"AUTH_FAILED: a lot of white space");
1916 auto msg5 = ProtoContext::read_control_string<std::string>(only_whitespace_buf);
1917 EXPECT_EQ(msg5,
"");
1920 auto msg6 = ProtoContext::read_control_string<std::string>(empty_buf);
1921 EXPECT_EQ(msg6,
"");
1940 std::vector<openvpn::ClientEvent::Base::Ptr>
events;
1945 asio::io_context io_context;
1946 ClientRandomAPI::Ptr rng_cli(
new ClientRandomAPI());
1962 std::move(cli_stats),
1964 clisessconf.cli_events = std::move(eqv_ptr);
1967 clisession->validate_and_post_cc_msg(
"valid message");
1970 EXPECT_TRUE(eqv->
events.empty());
1972 clisession->validate_and_post_cc_msg(
"invalid\nmessage");
1973 EXPECT_EQ(eqv->
events.size(), 1);
1974 auto ev = eqv->
events.back();
1978 EXPECT_EQ(uf->name,
"Invalid chars in control message");
1979 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)
@ CONTROL_HARD_RESET_CLIENT_V3
void data_encrypt(BufferAllocated &in_out)
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 TLSCryptContext::Ptr new_obj(SSLLib::Ctx libctx, const CryptoAlgs::Type digest_type, const CryptoAlgs::Type cipher_type)=0
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 generate(StrongRandomAPI &rng, const TLSCryptV2ServerKey &server_key, const std::string &metadata, const int metadata_type, const std::optional< std::uint32_t > key_id, SSLLib::Ctx libctx=nullptr)
Mint a fresh client key Kc and the WKc that carries it to a server.
std::string render() const
void extract_key(OpenVPNStaticKey &tls_key)
void generate(StrongRandomAPI &rng)
Mint a fresh server key, replacing any key already held.
void parse(const std::string &key_text)
std::string render() const
void extract_key(OpenVPNStaticKey &tls_key) const
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)
void write_string(const std::string &filename, const std::string &str)
RCPtr< BufferAllocatedRc > BufferPtr
std::string render_hex_number(T value, const bool caps=false)
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
const std::string & tls_crypt_v2_dir
bool tls_version_mismatch
bool use_tls_auth_with_tls_crypt_v2
bool use_dynamic_tls_crypt
std::string getTempDirPath(const std::string &fn)
static const char config[]
#define TLS_TIMEOUT_CLIENT
static void write_generated_tls_crypt_v2_keys(const std::string &dir, const std::string &client_fn, const std::uint32_t k_id, const std::string &metadata)
Mint a tls-crypt-v2 key pair the way the deployment tooling does.
#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, const std::string &tls_crypt_v2_dir=TEST_KEYCERT_DIR)
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)