2022-03-04 08:18:14 +00:00
|
|
|
#include "test_common.hh"
|
2021-09-07 09:23:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
// network parameters of example
|
|
|
|
constexpr char SENDER_ADDRESS[] = "127.0.0.1";
|
2022-07-16 10:56:53 +00:00
|
|
|
constexpr uint16_t SENDER_PORT = 9000;
|
2021-09-07 09:23:40 +00:00
|
|
|
|
|
|
|
constexpr char RECEIVER_ADDRESS[] = "127.0.0.1";
|
2022-08-24 11:35:07 +00:00
|
|
|
constexpr uint16_t RECEIVER_PORT = 9042;
|
2021-09-07 09:23:40 +00:00
|
|
|
|
2022-08-24 11:35:07 +00:00
|
|
|
constexpr auto EXAMPLE_DURATION_S = std::chrono::seconds(2);
|
2021-09-07 09:23:40 +00:00
|
|
|
|
|
|
|
// encryption parameters of example
|
|
|
|
enum Key_length { SRTP_128 = 128, SRTP_196 = 196, SRTP_256 = 256 };
|
2022-07-16 10:56:53 +00:00
|
|
|
constexpr Key_length KEY_SIZE = SRTP_128; // change this to change tested key length
|
2021-09-07 09:23:40 +00:00
|
|
|
constexpr int KEY_SIZE_BYTES = KEY_SIZE / 8;
|
|
|
|
constexpr int SALT_SIZE = 112;
|
|
|
|
constexpr int SALT_SIZE_BYTES = SALT_SIZE / 8;
|
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
void user_send_func(uint8_t key[KEY_SIZE_BYTES], uint8_t salt[SALT_SIZE_BYTES]);
|
|
|
|
void user_receive_func(uint8_t key[KEY_SIZE_BYTES], uint8_t salt[SALT_SIZE_BYTES]);
|
2022-08-24 11:35:07 +00:00
|
|
|
void zrtp_sender_func(uvgrtp::session* sender_session, int sender_port, int receiver_port, unsigned int flags);
|
|
|
|
void zrtp_receive_func(uvgrtp::session* receiver_session, int sender_port, int receiver_port, unsigned int flags);
|
2021-09-07 09:23:40 +00:00
|
|
|
|
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
// User key management test
|
2021-09-07 09:23:40 +00:00
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
TEST(EncryptionTests, srtp_user_keys)
|
2021-09-07 11:33:05 +00:00
|
|
|
{
|
2022-07-16 10:56:53 +00:00
|
|
|
std::cout << "Starting ZRTP sender thread" << std::endl;
|
2021-09-07 09:23:40 +00:00
|
|
|
uvgrtp::context ctx;
|
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
if (!ctx.crypto_enabled())
|
2021-09-07 09:23:40 +00:00
|
|
|
{
|
2022-07-16 10:56:53 +00:00
|
|
|
std::cout << "Please link crypto to uvgRTP library in order to tests its SRTP user keys!" << std::endl;
|
|
|
|
FAIL();
|
|
|
|
return;
|
2021-09-07 09:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t key[KEY_SIZE_BYTES] = { 0 };
|
|
|
|
uint8_t salt[SALT_SIZE_BYTES] = { 0 };
|
|
|
|
|
|
|
|
// initialize SRTP key and salt with dummy values
|
|
|
|
for (int i = 0; i < KEY_SIZE_BYTES; ++i)
|
|
|
|
key[i] = i;
|
|
|
|
|
|
|
|
for (int i = 0; i < SALT_SIZE_BYTES; ++i)
|
|
|
|
salt[i] = i * 2;
|
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
std::unique_ptr<std::thread> sender_thread = std::unique_ptr<std::thread>(new std::thread(user_send_func, key, salt));
|
|
|
|
std::unique_ptr<std::thread> receiver_thread = std::unique_ptr<std::thread>(new std::thread(user_receive_func, key, salt));
|
|
|
|
|
|
|
|
if (sender_thread && sender_thread->joinable())
|
|
|
|
{
|
|
|
|
sender_thread->join();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (receiver_thread && receiver_thread->joinable())
|
|
|
|
{
|
|
|
|
receiver_thread->join();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void user_send_func(uint8_t key[KEY_SIZE_BYTES], uint8_t salt[SALT_SIZE_BYTES])
|
|
|
|
{
|
|
|
|
uvgrtp::context ctx;
|
|
|
|
uvgrtp::session* sender_session = nullptr;
|
|
|
|
uvgrtp::media_stream* send = nullptr;
|
2021-09-07 09:23:40 +00:00
|
|
|
|
|
|
|
sender_session = ctx.create_session(RECEIVER_ADDRESS);
|
2021-09-07 11:33:05 +00:00
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
// Enable SRTP and let user manage the keys
|
|
|
|
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_USER;
|
|
|
|
if (KEY_SIZE == 192)
|
|
|
|
{
|
|
|
|
flags |= RCE_SRTP_KEYSIZE_192;
|
|
|
|
}
|
|
|
|
else if (KEY_SIZE == 256)
|
|
|
|
{
|
|
|
|
flags |= RCE_SRTP_KEYSIZE_256;
|
|
|
|
}
|
|
|
|
|
2021-09-07 11:33:05 +00:00
|
|
|
if (sender_session)
|
|
|
|
{
|
2022-07-16 10:56:53 +00:00
|
|
|
send = sender_session->create_stream(SENDER_PORT, RECEIVER_PORT, RTP_FORMAT_GENERIC, flags);
|
2021-09-07 11:33:05 +00:00
|
|
|
}
|
2021-09-07 09:23:40 +00:00
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
if (send)
|
|
|
|
send->add_srtp_ctx(key, salt); // add user context
|
|
|
|
|
2021-09-07 09:23:40 +00:00
|
|
|
EXPECT_NE(nullptr, sender_session);
|
|
|
|
EXPECT_NE(nullptr, send);
|
2021-09-07 11:33:05 +00:00
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
if (sender_session && send)
|
|
|
|
{
|
|
|
|
int test_packets = 10;
|
|
|
|
size_t frame_size = strlen((char*)"Hello, world!");
|
|
|
|
std::unique_ptr<uint8_t[]> test_frame = create_test_packet(RTP_FORMAT_GENERIC, 0, false, frame_size, RTP_NO_FLAGS);
|
|
|
|
send_packets(std::move(test_frame), frame_size, sender_session, send, test_packets, 0, true, RTP_NO_FLAGS);
|
2021-09-07 09:23:40 +00:00
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
cleanup_ms(sender_session, send);
|
|
|
|
cleanup_sess(ctx, sender_session);
|
|
|
|
}
|
2021-09-07 09:23:40 +00:00
|
|
|
}
|
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
void user_receive_func(uint8_t key[KEY_SIZE_BYTES], uint8_t salt[SALT_SIZE_BYTES])
|
2021-09-07 09:23:40 +00:00
|
|
|
{
|
|
|
|
/* See sending.cc for more details */
|
|
|
|
uvgrtp::context ctx;
|
|
|
|
uvgrtp::session* receiver_session = ctx.create_session(SENDER_ADDRESS);
|
|
|
|
|
|
|
|
/* Enable SRTP and let user manage keys */
|
|
|
|
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_USER;
|
|
|
|
|
2022-07-16 10:56:53 +00:00
|
|
|
if (KEY_SIZE == 192)
|
|
|
|
{
|
|
|
|
flags |= RCE_SRTP_KEYSIZE_192;
|
|
|
|
}
|
|
|
|
else if (KEY_SIZE == 256)
|
|
|
|
{
|
|
|
|
flags |= RCE_SRTP_KEYSIZE_256;
|
|
|
|
}
|
2021-09-07 09:23:40 +00:00
|
|
|
|
|
|
|
/* See sending.cc for more details about create_stream() */
|
2021-09-07 11:33:05 +00:00
|
|
|
uvgrtp::media_stream* recv = nullptr;
|
2022-07-16 10:56:53 +00:00
|
|
|
|
2021-09-07 11:33:05 +00:00
|
|
|
if (receiver_session)
|
|
|
|
{
|
2022-07-16 10:56:53 +00:00
|
|
|
recv = receiver_session->create_stream(RECEIVER_PORT, SENDER_PORT, RTP_FORMAT_GENERIC, flags);
|
2021-09-07 11:33:05 +00:00
|
|
|
}
|
|
|
|
|
2021-09-07 09:23:40 +00:00
|
|
|
if (recv)
|
2022-07-16 10:56:53 +00:00
|
|
|
{
|
2021-09-07 09:23:40 +00:00
|
|
|
recv->add_srtp_ctx(key, salt);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto start = std::chrono::steady_clock::now();
|
|
|
|
|
|
|
|
uvgrtp::frame::rtp_frame* frame = nullptr;
|
|
|
|
|
|
|
|
if (recv)
|
|
|
|
{
|
2022-07-16 10:56:53 +00:00
|
|
|
while (std::chrono::steady_clock::now() - start < EXAMPLE_DURATION_S)
|
|
|
|
{
|
|
|
|
frame = recv->pull_frame(10);
|
|
|
|
if (frame)
|
|
|
|
{
|
|
|
|
process_rtp_frame(frame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup_ms(receiver_session, recv);
|
|
|
|
cleanup_sess(ctx, receiver_session);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-24 11:35:07 +00:00
|
|
|
// ZRTP key management tests
|
2022-07-16 10:56:53 +00:00
|
|
|
|
|
|
|
TEST(EncryptionTests, zrtp)
|
|
|
|
{
|
|
|
|
uvgrtp::context ctx;
|
|
|
|
|
|
|
|
if (!ctx.crypto_enabled())
|
|
|
|
{
|
|
|
|
std::cout << "Please link crypto to uvgRTP library in order to tests its ZRTP feature!" << std::endl;
|
|
|
|
FAIL();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-08-24 11:35:07 +00:00
|
|
|
uvgrtp::session* sender_session = ctx.create_session(RECEIVER_ADDRESS, SENDER_ADDRESS);
|
|
|
|
uvgrtp::session* receiver_session = ctx.create_session(SENDER_ADDRESS, RECEIVER_ADDRESS);
|
|
|
|
|
|
|
|
unsigned zrtp_flags = RCE_SRTP | RCE_SRTP_KMNGMNT_ZRTP;
|
|
|
|
|
|
|
|
std::unique_ptr<std::thread> sender_thread =
|
|
|
|
std::unique_ptr<std::thread>(new std::thread(zrtp_sender_func, sender_session, SENDER_PORT, RECEIVER_PORT, zrtp_flags));
|
|
|
|
|
|
|
|
std::unique_ptr<std::thread> receiver_thread =
|
|
|
|
std::unique_ptr<std::thread>(new std::thread(zrtp_receive_func, receiver_session, SENDER_PORT, RECEIVER_PORT, zrtp_flags));
|
2022-07-16 10:56:53 +00:00
|
|
|
|
|
|
|
if (sender_thread && sender_thread->joinable())
|
|
|
|
{
|
|
|
|
sender_thread->join();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (receiver_thread && receiver_thread->joinable())
|
|
|
|
{
|
|
|
|
receiver_thread->join();
|
|
|
|
}
|
2022-08-31 07:06:37 +00:00
|
|
|
|
|
|
|
cleanup_sess(ctx, sender_session);
|
|
|
|
cleanup_sess(ctx, receiver_session);
|
2022-07-16 10:56:53 +00:00
|
|
|
}
|
|
|
|
|
2022-08-24 11:35:07 +00:00
|
|
|
TEST(EncryptionTests, zrtp_multistream)
|
2022-07-16 10:56:53 +00:00
|
|
|
{
|
|
|
|
uvgrtp::context ctx;
|
2022-08-24 11:35:07 +00:00
|
|
|
|
|
|
|
if (!ctx.crypto_enabled())
|
|
|
|
{
|
|
|
|
std::cout << "Please link crypto to uvgRTP library in order to tests its ZRTP feature!" << std::endl;
|
|
|
|
FAIL();
|
|
|
|
return;
|
|
|
|
}
|
2022-07-16 10:56:53 +00:00
|
|
|
|
|
|
|
/* Enable SRTP and ZRTP */
|
2022-08-24 11:35:07 +00:00
|
|
|
unsigned zrtp_flags = RCE_SRTP | RCE_SRTP_KMNGMNT_ZRTP;
|
|
|
|
|
|
|
|
// only one of the streams should perform DH
|
|
|
|
unsigned int no_dh_flags = zrtp_flags | RCE_ZRTP_MULTISTREAM_NO_DH;
|
|
|
|
|
|
|
|
|
|
|
|
uvgrtp::session* sender_session = ctx.create_session(RECEIVER_ADDRESS, SENDER_ADDRESS);
|
|
|
|
uvgrtp::session* receiver_session = ctx.create_session(SENDER_ADDRESS, RECEIVER_ADDRESS);
|
|
|
|
|
|
|
|
std::unique_ptr<std::thread> sender_thread1 =
|
2022-08-25 15:34:47 +00:00
|
|
|
std::unique_ptr<std::thread>(new std::thread(zrtp_sender_func, sender_session, SENDER_PORT + 2, RECEIVER_PORT + 2, zrtp_flags));
|
2022-09-01 10:02:56 +00:00
|
|
|
|
|
|
|
std::unique_ptr<std::thread> receiver_thread1 =
|
|
|
|
std::unique_ptr<std::thread>(new std::thread(zrtp_receive_func, receiver_session, SENDER_PORT + 2, RECEIVER_PORT + 2, zrtp_flags));
|
|
|
|
|
2022-08-24 11:35:07 +00:00
|
|
|
std::unique_ptr<std::thread> sender_thread2 =
|
2022-08-25 15:34:47 +00:00
|
|
|
std::unique_ptr<std::thread>(new std::thread(zrtp_sender_func, sender_session, SENDER_PORT + 4, RECEIVER_PORT + 4, no_dh_flags));
|
2022-08-24 11:35:07 +00:00
|
|
|
|
|
|
|
std::unique_ptr<std::thread> receiver_thread2 =
|
2022-08-25 15:34:47 +00:00
|
|
|
std::unique_ptr<std::thread>(new std::thread(zrtp_receive_func, receiver_session, SENDER_PORT + 4, RECEIVER_PORT + 4, no_dh_flags));
|
2022-08-24 11:35:07 +00:00
|
|
|
|
2022-09-01 10:02:56 +00:00
|
|
|
if (receiver_thread1 && receiver_thread1->joinable())
|
|
|
|
{
|
|
|
|
receiver_thread1->join();
|
|
|
|
}
|
|
|
|
|
2022-08-24 11:35:07 +00:00
|
|
|
if (sender_thread1 && sender_thread1->joinable())
|
|
|
|
{
|
|
|
|
sender_thread1->join();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sender_thread2 && sender_thread2->joinable())
|
|
|
|
{
|
|
|
|
sender_thread2->join();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (receiver_thread2 && receiver_thread2->joinable())
|
|
|
|
{
|
|
|
|
receiver_thread2->join();
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup_sess(ctx, sender_session);
|
|
|
|
cleanup_sess(ctx, receiver_session);
|
|
|
|
}
|
|
|
|
|
|
|
|
void zrtp_sender_func(uvgrtp::session* sender_session, int sender_port, int receiver_port, unsigned int flags)
|
|
|
|
{
|
|
|
|
std::cout << "Starting ZRTP sender thread" << std::endl;
|
2022-07-16 10:56:53 +00:00
|
|
|
|
|
|
|
/* See sending.cc for more details about create_stream() */
|
|
|
|
uvgrtp::media_stream* send = nullptr;
|
|
|
|
|
|
|
|
if (sender_session)
|
|
|
|
{
|
2022-08-24 11:35:07 +00:00
|
|
|
send = sender_session->create_stream(sender_port, receiver_port, RTP_FORMAT_GENERIC, flags);
|
2022-07-16 10:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto start = std::chrono::steady_clock::now();
|
|
|
|
|
|
|
|
uvgrtp::frame::rtp_frame* frame = nullptr;
|
|
|
|
|
|
|
|
if (send)
|
|
|
|
{
|
|
|
|
int test_packets = 10;
|
|
|
|
size_t packet_size = 1000;
|
2022-08-24 11:35:07 +00:00
|
|
|
int packet_interval_ms = EXAMPLE_DURATION_S.count() * 1000 / test_packets;
|
2022-07-16 10:56:53 +00:00
|
|
|
|
|
|
|
std::unique_ptr<uint8_t[]> test_frame = create_test_packet(RTP_FORMAT_GENERIC, 0, false, packet_size, RTP_NO_FLAGS);
|
2022-08-24 11:35:07 +00:00
|
|
|
send_packets(std::move(test_frame), packet_size, sender_session, send, test_packets, packet_interval_ms, false, RTP_NO_FLAGS);
|
2022-07-16 10:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cleanup_ms(sender_session, send);
|
|
|
|
}
|
|
|
|
|
2022-08-24 11:35:07 +00:00
|
|
|
void zrtp_receive_func(uvgrtp::session* receiver_session, int sender_port, int receiver_port, unsigned int flags)
|
2022-07-16 10:56:53 +00:00
|
|
|
{
|
|
|
|
std::cout << "Starting ZRTP receiver thread" << std::endl;
|
|
|
|
|
|
|
|
/* See sending.cc for more details about create_stream() */
|
|
|
|
uvgrtp::media_stream* recv = nullptr;
|
|
|
|
|
|
|
|
if (receiver_session)
|
|
|
|
{
|
2022-08-24 11:35:07 +00:00
|
|
|
recv = receiver_session->create_stream(receiver_port, sender_port, RTP_FORMAT_GENERIC, flags);
|
2022-07-16 10:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto start = std::chrono::steady_clock::now();
|
|
|
|
|
|
|
|
uvgrtp::frame::rtp_frame* frame = nullptr;
|
|
|
|
|
|
|
|
if (recv)
|
|
|
|
{
|
|
|
|
while (std::chrono::steady_clock::now() - start < EXAMPLE_DURATION_S)
|
2021-09-07 09:23:40 +00:00
|
|
|
{
|
|
|
|
frame = recv->pull_frame(10);
|
|
|
|
if (frame)
|
|
|
|
{
|
2022-03-25 08:31:48 +00:00
|
|
|
process_rtp_frame(frame);
|
2021-09-07 09:23:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-04 08:18:14 +00:00
|
|
|
cleanup_ms(receiver_session, recv);
|
2021-09-07 09:23:40 +00:00
|
|
|
}
|