From 01116a34b60191e97831860a96be81fafc5026ec Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Thu, 29 Mar 2018 21:55:48 +0200 Subject: test: add testcase for media encryption --- test/call.c | 61 +++++++++++++++++++++++- test/main.c | 1 + test/mock/mock_menc.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/srcs.mk | 1 + test/test.h | 9 ++++ 5 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 test/mock/mock_menc.c (limited to 'test') diff --git a/test/call.c b/test/call.c index 73f3ebd..2472afe 100644 --- a/test/call.c +++ b/test/call.c @@ -830,8 +830,15 @@ static void float_sample_handler(const void *sampv, size_t sampc, void *arg) (void)sampv; (void)sampc; - if (sampc && fix->a.n_established && fix->b.n_established) + /* Wait until the call is established and the incoming + * audio samples are successfully decoded. + */ + if (sampc && fix->a.n_established && fix->b.n_established && + audio_rxaubuf_started(call_audio(ua_call(fix->a.ua))) && + audio_rxaubuf_started(call_audio(ua_call(fix->b.ua))) + ) { re_cancel(); + } } @@ -906,3 +913,55 @@ int test_call_format_float(void) out: return err; } + + +int test_call_mediaenc(void) +{ + struct fixture fix, *f = &fix; + struct ausrc *ausrc = NULL; + struct auplay *auplay = NULL; + int err = 0; + + mock_menc_register(); + + /* Enable a dummy media encryption protocol */ + fixture_init_prm(f, ";mediaenc=xrtp;ptime=1"); + + err = mock_ausrc_register(&ausrc); + TEST_ERR(err); + err = mock_auplay_register(&auplay, float_sample_handler, f); + TEST_ERR(err); + + f->estab_action = ACTION_NOTHING; + + f->behaviour = BEHAVIOUR_ANSWER; + + /* Make a call from A to B */ + err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF); + TEST_ERR(err); + + /* run main-loop with timeout, wait for events */ + err = re_main_timeout(5000); + TEST_ERR(err); + TEST_ERR(fix.err); + + ASSERT_EQ(1, fix.a.n_established); + ASSERT_EQ(0, fix.a.n_closed); + + ASSERT_EQ(1, fix.b.n_established); + ASSERT_EQ(0, fix.b.n_closed); + + /* XXX: verify that the call was encrypted */ + + out: + fixture_close(f); + mem_deref(auplay); + mem_deref(ausrc); + + mock_menc_unregister(); + + if (fix.err) + return fix.err; + + return err; +} diff --git a/test/main.c b/test/main.c index 09ff19e..01937f4 100644 --- a/test/main.c +++ b/test/main.c @@ -30,6 +30,7 @@ static const struct test tests[] = { TEST(test_call_answer_hangup_b), TEST(test_call_reject), TEST(test_call_rtp_timeout), + TEST(test_call_mediaenc), TEST(test_call_multiple), TEST(test_call_max), TEST(test_call_dtmf), diff --git a/test/mock/mock_menc.c b/test/mock/mock_menc.c new file mode 100644 index 0000000..b554646 --- /dev/null +++ b/test/mock/mock_menc.c @@ -0,0 +1,125 @@ +/** + * @file mock/mock_menc.c Mock media encryption + * + * Copyright (C) 2010 - 2018 Creytiv.com + */ + +#include +#include +#include +#include "../test.h" + + +#define SECRET_KEY 0xdd + + +struct menc_media { + void *rtpsock; + struct udp_helper *uh_rtp; +}; + + +/* + * Encrypt/decrypt an RTP payload with a dummy key. + * We use a simple XOR scheme for simplicity. + */ +static void mock_crypt(struct mbuf *mb) +{ + size_t i, len = mbuf_get_left(mb); + + for (i = RTP_HEADER_SIZE; i < len; i++) { + mb->buf[mb->pos + i] ^= SECRET_KEY; + } +} + + +static void media_destructor(void *data) +{ + struct menc_media *mm = data; + + mem_deref(mm->uh_rtp); + mem_deref(mm->rtpsock); +} + + +static bool send_handler(int *err, struct sa *dst, struct mbuf *mb, void *arg) +{ + struct menc_media *mm = arg; + (void)mm; + (void)dst; + + mock_crypt(mb); + + return false; /* continue processing */ +} + + +static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg) +{ + struct menc_media *mm = arg; + (void)mm; + (void)src; + + mock_crypt(mb); + + return false; /* continue processing */ +} + + +static int mock_media_alloc(struct menc_media **mmp, struct menc_sess *sess, + struct rtp_sock *rtp, int proto, + void *rtpsock, void *rtcpsock, + struct sdp_media *sdpm) +{ + struct menc_media *mm; + const int layer = 10; /* above zero */ + int err = 0; + (void)sess; + (void)rtp; + (void)rtcpsock; + + if (!mmp || !sdpm) + return EINVAL; + if (proto != IPPROTO_UDP) + return EPROTONOSUPPORT; + + mm = *mmp; + if (!mm) { + mm = mem_zalloc(sizeof(*mm), media_destructor); + if (!mm) + return ENOMEM; + + mm->rtpsock = mem_ref(rtpsock); + err = udp_register_helper(&mm->uh_rtp, rtpsock, layer, + send_handler, recv_handler, mm); + if (err) + goto out; + + *mmp = mm; + } + + out: + if (err) + mem_deref(mm); + + return err; +} + + +static struct menc menc_mock = { + .id = "XRTP", + .sdp_proto = "RTP/XAVP", + .mediah = mock_media_alloc +}; + + +void mock_menc_register(void) +{ + menc_register(baresip_mencl(), &menc_mock); +} + + +void mock_menc_unregister(void) +{ + menc_unregister(&menc_mock); +} diff --git a/test/srcs.mk b/test/srcs.mk index bdb0d0b..6cd6d3d 100644 --- a/test/srcs.mk +++ b/test/srcs.mk @@ -44,6 +44,7 @@ endif TEST_SRCS += mock/mock_aucodec.c TEST_SRCS += mock/mock_auplay.c TEST_SRCS += mock/mock_ausrc.c +TEST_SRCS += mock/mock_menc.c ifneq ($(USE_VIDEO),) TEST_SRCS += mock/mock_vidsrc.c TEST_SRCS += mock/mock_vidcodec.c diff --git a/test/test.h b/test/test.h index 7977272..8072cfd 100644 --- a/test/test.h +++ b/test/test.h @@ -149,6 +149,14 @@ int mock_auplay_register(struct auplay **auplayp, mock_sample_h *sampleh, void *arg); +/* + * Mock Media encryption + */ + +void mock_menc_register(void); +void mock_menc_unregister(void); + + /* * Mock Video-source */ @@ -208,6 +216,7 @@ int test_call_video(void); int test_call_aulevel(void); int test_call_progress(void); int test_call_format_float(void); +int test_call_mediaenc(void); #ifdef USE_VIDEO int test_video(void); -- cgit v1.2.3