mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Upgrade libsrtp from 2.0.0 to 2.3.0, with source code. 4.0.79
This commit is contained in:
parent
3749d4d833
commit
8089fc004c
111 changed files with 45307 additions and 5 deletions
713
trunk/3rdparty/libsrtp-2-fit/test/cutest.h
vendored
Normal file
713
trunk/3rdparty/libsrtp-2-fit/test/cutest.h
vendored
Normal file
|
@ -0,0 +1,713 @@
|
|||
/*
|
||||
* CUTest -- C/C++ Unit Test facility
|
||||
* <http://github.com/mity/cutest>
|
||||
*
|
||||
* Copyright (c) 2013-2017 Martin Mitas
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CUTEST_H__
|
||||
#define CUTEST_H__
|
||||
|
||||
/************************
|
||||
*** Public interface ***
|
||||
************************/
|
||||
|
||||
/* By default, <cutest.h> provides the main program entry point (function
|
||||
* main()). However, if the test suite is composed of multiple source files
|
||||
* which include <cutest.h>, then this causes a problem of multiple main()
|
||||
* definitions. To avoid this problem, #define macro TEST_NO_MAIN in all
|
||||
* compilation units but one.
|
||||
*/
|
||||
|
||||
/* Macro to specify list of unit tests in the suite.
|
||||
* The unit test implementation MUST provide list of unit tests it implements
|
||||
* with this macro:
|
||||
*
|
||||
* TEST_LIST = {
|
||||
* { "test1_name", test1_func_ptr },
|
||||
* { "test2_name", test2_func_ptr },
|
||||
* ...
|
||||
* { 0 }
|
||||
* };
|
||||
*
|
||||
* The list specifies names of each test (must be unique) and pointer to
|
||||
* a function implementing it. The function does not take any arguments
|
||||
* and has no return values, i.e. every test function has tp be compatible
|
||||
* with this prototype:
|
||||
*
|
||||
* void test_func(void);
|
||||
*/
|
||||
#define TEST_LIST const struct test__ test_list__[]
|
||||
|
||||
/* Macros for testing whether an unit test succeeds or fails. These macros
|
||||
* can be used arbitrarily in functions implementing the unit tests.
|
||||
*
|
||||
* If any condition fails throughout execution of a test, the test fails.
|
||||
*
|
||||
* TEST_CHECK takes only one argument (the condition), TEST_CHECK_ allows
|
||||
* also to specify an error message to print out if the condition fails.
|
||||
* (It expects printf-like format string and its parameters). The macros
|
||||
* return non-zero (condition passes) or 0 (condition fails).
|
||||
*
|
||||
* That can be useful when more conditions should be checked only if some
|
||||
* preceding condition passes, as illustrated in this code snippet:
|
||||
*
|
||||
* SomeStruct* ptr = allocate_some_struct();
|
||||
* if(TEST_CHECK(ptr != NULL)) {
|
||||
* TEST_CHECK(ptr->member1 < 100);
|
||||
* TEST_CHECK(ptr->member2 > 200);
|
||||
* }
|
||||
*/
|
||||
#define TEST_CHECK_(cond, ...) \
|
||||
test_check__((cond), __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define TEST_CHECK(cond) test_check__((cond), __FILE__, __LINE__, "%s", #cond)
|
||||
|
||||
/**********************
|
||||
*** Implementation ***
|
||||
**********************/
|
||||
|
||||
/* The unit test files should not rely on anything below. */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
|
||||
#define CUTEST_UNIX__ 1
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
|
||||
#define CUTEST_WIN__ 1
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
/* Note our global private identifiers end with '__' to mitigate risk of clash
|
||||
* with the unit tests implementation. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct test__ {
|
||||
const char *name;
|
||||
void (*func)(void);
|
||||
};
|
||||
|
||||
extern const struct test__ test_list__[];
|
||||
|
||||
int test_check__(int cond, const char *file, int line, const char *fmt, ...);
|
||||
|
||||
#ifndef TEST_NO_MAIN
|
||||
|
||||
static char *test_argv0__ = NULL;
|
||||
static int test_count__ = 0;
|
||||
static int test_no_exec__ = 0;
|
||||
static int test_no_summary__ = 0;
|
||||
static int test_skip_mode__ = 0;
|
||||
|
||||
static int test_stat_failed_units__ = 0;
|
||||
static int test_stat_run_units__ = 0;
|
||||
|
||||
static const struct test__ *test_current_unit__ = NULL;
|
||||
static int test_current_already_logged__ = 0;
|
||||
static int test_verbose_level__ = 2;
|
||||
static int test_current_failures__ = 0;
|
||||
static int test_colorize__ = 0;
|
||||
|
||||
#define CUTEST_COLOR_DEFAULT__ 0
|
||||
#define CUTEST_COLOR_GREEN__ 1
|
||||
#define CUTEST_COLOR_RED__ 2
|
||||
#define CUTEST_COLOR_DEFAULT_INTENSIVE__ 3
|
||||
#define CUTEST_COLOR_GREEN_INTENSIVE__ 4
|
||||
#define CUTEST_COLOR_RED_INTENSIVE__ 5
|
||||
|
||||
static size_t test_print_in_color__(int color, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[256];
|
||||
size_t n;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
|
||||
if (!test_colorize__) {
|
||||
return printf("%s", buffer);
|
||||
}
|
||||
|
||||
#if defined CUTEST_UNIX__
|
||||
{
|
||||
const char *col_str;
|
||||
switch (color) {
|
||||
case CUTEST_COLOR_GREEN__:
|
||||
col_str = "\033[0;32m";
|
||||
break;
|
||||
case CUTEST_COLOR_RED__:
|
||||
col_str = "\033[0;31m";
|
||||
break;
|
||||
case CUTEST_COLOR_GREEN_INTENSIVE__:
|
||||
col_str = "\033[1;32m";
|
||||
break;
|
||||
case CUTEST_COLOR_RED_INTENSIVE__:
|
||||
col_str = "\033[1;30m";
|
||||
break;
|
||||
case CUTEST_COLOR_DEFAULT_INTENSIVE__:
|
||||
col_str = "\033[1m";
|
||||
break;
|
||||
default:
|
||||
col_str = "\033[0m";
|
||||
break;
|
||||
}
|
||||
printf("%s", col_str);
|
||||
n = printf("%s", buffer);
|
||||
printf("\033[0m");
|
||||
return n;
|
||||
}
|
||||
#elif defined CUTEST_WIN__
|
||||
{
|
||||
HANDLE h;
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
WORD attr;
|
||||
|
||||
h = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
GetConsoleScreenBufferInfo(h, &info);
|
||||
|
||||
switch (color) {
|
||||
case CUTEST_COLOR_GREEN__:
|
||||
attr = FOREGROUND_GREEN;
|
||||
break;
|
||||
case CUTEST_COLOR_RED__:
|
||||
attr = FOREGROUND_RED;
|
||||
break;
|
||||
case CUTEST_COLOR_GREEN_INTENSIVE__:
|
||||
attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case CUTEST_COLOR_RED_INTENSIVE__:
|
||||
attr = FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case CUTEST_COLOR_DEFAULT_INTENSIVE__:
|
||||
attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED |
|
||||
FOREGROUND_INTENSITY;
|
||||
break;
|
||||
default:
|
||||
attr = 0;
|
||||
break;
|
||||
}
|
||||
if (attr != 0)
|
||||
SetConsoleTextAttribute(h, attr);
|
||||
n = printf("%s", buffer);
|
||||
SetConsoleTextAttribute(h, info.wAttributes);
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
n = printf("%s", buffer);
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
|
||||
int test_check__(int cond, const char *file, int line, const char *fmt, ...)
|
||||
{
|
||||
const char *result_str;
|
||||
int result_color;
|
||||
int verbose_level;
|
||||
|
||||
if (cond) {
|
||||
result_str = "ok";
|
||||
result_color = CUTEST_COLOR_GREEN__;
|
||||
verbose_level = 3;
|
||||
} else {
|
||||
if (!test_current_already_logged__ && test_current_unit__ != NULL) {
|
||||
printf("[ ");
|
||||
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, "FAILED");
|
||||
printf(" ]\n");
|
||||
}
|
||||
result_str = "failed";
|
||||
result_color = CUTEST_COLOR_RED__;
|
||||
verbose_level = 2;
|
||||
test_current_failures__++;
|
||||
test_current_already_logged__++;
|
||||
}
|
||||
|
||||
if (test_verbose_level__ >= verbose_level) {
|
||||
size_t n = 0;
|
||||
va_list args;
|
||||
|
||||
printf(" ");
|
||||
|
||||
if (file != NULL)
|
||||
n += printf("%s:%d: Check ", file, line);
|
||||
|
||||
va_start(args, fmt);
|
||||
n += vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
printf("... ");
|
||||
test_print_in_color__(result_color, result_str);
|
||||
printf("\n");
|
||||
test_current_already_logged__++;
|
||||
}
|
||||
|
||||
return (cond != 0);
|
||||
}
|
||||
|
||||
static void test_list_names__(void)
|
||||
{
|
||||
const struct test__ *test;
|
||||
|
||||
printf("Unit tests:\n");
|
||||
for (test = &test_list__[0]; test->func != NULL; test++)
|
||||
printf(" %s\n", test->name);
|
||||
}
|
||||
|
||||
static const struct test__ *test_by_name__(const char *name)
|
||||
{
|
||||
const struct test__ *test;
|
||||
|
||||
for (test = &test_list__[0]; test->func != NULL; test++) {
|
||||
if (strcmp(test->name, name) == 0)
|
||||
return test;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Call directly the given test unit function. */
|
||||
static int test_do_run__(const struct test__ *test)
|
||||
{
|
||||
test_current_unit__ = test;
|
||||
test_current_failures__ = 0;
|
||||
test_current_already_logged__ = 0;
|
||||
|
||||
if (test_verbose_level__ >= 3) {
|
||||
test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__, "Test %s:\n",
|
||||
test->name);
|
||||
test_current_already_logged__++;
|
||||
} else if (test_verbose_level__ >= 1) {
|
||||
size_t n;
|
||||
char spaces[32];
|
||||
|
||||
n = test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__,
|
||||
"Test %s... ", test->name);
|
||||
memset(spaces, ' ', sizeof(spaces));
|
||||
if (n < sizeof(spaces))
|
||||
printf("%.*s", (int)(sizeof(spaces) - n), spaces);
|
||||
} else {
|
||||
test_current_already_logged__ = 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
try {
|
||||
#endif
|
||||
|
||||
/* This is good to do for case the test unit e.g. crashes. */
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
test->func();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} catch (std::exception &e) {
|
||||
const char *what = e.what();
|
||||
if (what != NULL)
|
||||
test_check__(0, NULL, 0, "Threw std::exception: %s", what);
|
||||
else
|
||||
test_check__(0, NULL, 0, "Threw std::exception");
|
||||
} catch (...) {
|
||||
test_check__(0, NULL, 0, "Threw an exception");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (test_verbose_level__ >= 3) {
|
||||
switch (test_current_failures__) {
|
||||
case 0:
|
||||
test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__,
|
||||
" All conditions have passed.\n\n");
|
||||
break;
|
||||
case 1:
|
||||
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__,
|
||||
" One condition has FAILED.\n\n");
|
||||
break;
|
||||
default:
|
||||
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__,
|
||||
" %d conditions have FAILED.\n\n",
|
||||
test_current_failures__);
|
||||
break;
|
||||
}
|
||||
} else if (test_verbose_level__ >= 1 && test_current_failures__ == 0) {
|
||||
printf("[ ");
|
||||
test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__, "OK");
|
||||
printf(" ]\n");
|
||||
}
|
||||
|
||||
test_current_unit__ = NULL;
|
||||
return (test_current_failures__ == 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
#if defined(CUTEST_UNIX__) || defined(CUTEST_WIN__)
|
||||
/* Called if anything goes bad in cutest, or if the unit test ends in other
|
||||
* way then by normal returning from its function (e.g. exception or some
|
||||
* abnormal child process termination). */
|
||||
static void test_error__(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (test_verbose_level__ == 0)
|
||||
return;
|
||||
|
||||
if (test_verbose_level__ <= 2 && !test_current_already_logged__ &&
|
||||
test_current_unit__ != NULL) {
|
||||
printf("[ ");
|
||||
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, "FAILED");
|
||||
printf(" ]\n");
|
||||
}
|
||||
|
||||
if (test_verbose_level__ >= 2) {
|
||||
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, " Error: ");
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Trigger the unit test. If possible (and not suppressed) it starts a child
|
||||
* process who calls test_do_run__(), otherwise it calls test_do_run__()
|
||||
* directly. */
|
||||
static void test_run__(const struct test__ *test)
|
||||
{
|
||||
int failed = 1;
|
||||
|
||||
test_current_unit__ = test;
|
||||
test_current_already_logged__ = 0;
|
||||
|
||||
if (!test_no_exec__) {
|
||||
#if defined(CUTEST_UNIX__)
|
||||
|
||||
pid_t pid;
|
||||
int exit_code;
|
||||
|
||||
pid = fork();
|
||||
if (pid == (pid_t)-1) {
|
||||
test_error__("Cannot fork. %s [%d]", strerror(errno), errno);
|
||||
failed = 1;
|
||||
} else if (pid == 0) {
|
||||
/* Child: Do the test. */
|
||||
failed = (test_do_run__(test) != 0);
|
||||
exit(failed ? 1 : 0);
|
||||
} else {
|
||||
/* Parent: Wait until child terminates and analyze its exit code. */
|
||||
waitpid(pid, &exit_code, 0);
|
||||
if (WIFEXITED(exit_code)) {
|
||||
switch (WEXITSTATUS(exit_code)) {
|
||||
case 0:
|
||||
failed = 0;
|
||||
break; /* test has passed. */
|
||||
case 1: /* noop */
|
||||
break; /* "normal" failure. */
|
||||
default:
|
||||
test_error__("Unexpected exit code [%d]",
|
||||
WEXITSTATUS(exit_code));
|
||||
}
|
||||
} else if (WIFSIGNALED(exit_code)) {
|
||||
char tmp[32];
|
||||
const char *signame;
|
||||
switch (WTERMSIG(exit_code)) {
|
||||
case SIGINT:
|
||||
signame = "SIGINT";
|
||||
break;
|
||||
case SIGHUP:
|
||||
signame = "SIGHUP";
|
||||
break;
|
||||
case SIGQUIT:
|
||||
signame = "SIGQUIT";
|
||||
break;
|
||||
case SIGABRT:
|
||||
signame = "SIGABRT";
|
||||
break;
|
||||
case SIGKILL:
|
||||
signame = "SIGKILL";
|
||||
break;
|
||||
case SIGSEGV:
|
||||
signame = "SIGSEGV";
|
||||
break;
|
||||
case SIGILL:
|
||||
signame = "SIGILL";
|
||||
break;
|
||||
case SIGTERM:
|
||||
signame = "SIGTERM";
|
||||
break;
|
||||
default:
|
||||
sprintf(tmp, "signal %d", WTERMSIG(exit_code));
|
||||
signame = tmp;
|
||||
break;
|
||||
}
|
||||
test_error__("Test interrupted by %s", signame);
|
||||
} else {
|
||||
test_error__("Test ended in an unexpected way [%d]", exit_code);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(CUTEST_WIN__)
|
||||
|
||||
char buffer[512] = { 0 };
|
||||
STARTUPINFOA startupInfo = { 0 };
|
||||
PROCESS_INFORMATION processInfo;
|
||||
DWORD exitCode;
|
||||
|
||||
/* Windows has no fork(). So we propagate all info into the child
|
||||
* through a command line arguments. */
|
||||
_snprintf(buffer, sizeof(buffer) - 1,
|
||||
"%s --no-exec --no-summary --verbose=%d --color=%s -- \"%s\"",
|
||||
test_argv0__, test_verbose_level__,
|
||||
test_colorize__ ? "always" : "never", test->name);
|
||||
startupInfo.cb = sizeof(STARTUPINFO);
|
||||
if (CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL,
|
||||
&startupInfo, &processInfo)) {
|
||||
WaitForSingleObject(processInfo.hProcess, INFINITE);
|
||||
GetExitCodeProcess(processInfo.hProcess, &exitCode);
|
||||
CloseHandle(processInfo.hThread);
|
||||
CloseHandle(processInfo.hProcess);
|
||||
failed = (exitCode != 0);
|
||||
} else {
|
||||
test_error__("Cannot create unit test subprocess [%ld].",
|
||||
GetLastError());
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* A platform where we don't know how to run child process. */
|
||||
failed = (test_do_run__(test) != 0);
|
||||
|
||||
#endif
|
||||
|
||||
} else {
|
||||
/* Child processes suppressed through --no-exec. */
|
||||
failed = (test_do_run__(test) != 0);
|
||||
}
|
||||
|
||||
test_current_unit__ = NULL;
|
||||
|
||||
test_stat_run_units__++;
|
||||
if (failed)
|
||||
test_stat_failed_units__++;
|
||||
}
|
||||
|
||||
#if defined(CUTEST_WIN__)
|
||||
/* Callback for SEH events. */
|
||||
static LONG CALLBACK test_exception_filter__(EXCEPTION_POINTERS *ptrs)
|
||||
{
|
||||
test_error__("Unhandled SEH exception %08lx at %p.",
|
||||
ptrs->ExceptionRecord->ExceptionCode,
|
||||
ptrs->ExceptionRecord->ExceptionAddress);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void test_help__(void)
|
||||
{
|
||||
printf("Usage: %s [options] [test...]\n", test_argv0__);
|
||||
printf("Run the specified unit tests; or if the option '--skip' is used, "
|
||||
"run all\n");
|
||||
printf("tests in the suite but those listed. By default, if no tests are "
|
||||
"specified\n");
|
||||
printf("on the command line, all unit tests in the suite are run.\n");
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(
|
||||
" -s, --skip Execute all unit tests but the listed ones\n");
|
||||
printf(" --no-exec Do not execute unit tests as child "
|
||||
"processes\n");
|
||||
printf(
|
||||
" --no-summary Suppress printing of test results summary\n");
|
||||
printf(" -l, --list List unit tests in the suite and exit\n");
|
||||
printf(" -v, --verbose Enable more verbose output\n");
|
||||
printf(" --verbose=LEVEL Set verbose level to LEVEL:\n");
|
||||
printf(" 0 ... Be silent\n");
|
||||
printf(" 1 ... Output one line per test (and "
|
||||
"summary)\n");
|
||||
printf(" 2 ... As 1 and failed conditions (this "
|
||||
"is default)\n");
|
||||
printf(" 3 ... As 1 and all conditions (and "
|
||||
"extended summary)\n");
|
||||
printf(" --color=WHEN Enable colorized output (WHEN is one of "
|
||||
"'auto', 'always', 'never')\n");
|
||||
printf(" -h, --help Display this help and exit\n");
|
||||
printf("\n");
|
||||
test_list_names__();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const struct test__ **tests = NULL;
|
||||
int i, j, n = 0;
|
||||
int seen_double_dash = 0;
|
||||
|
||||
test_argv0__ = argv[0];
|
||||
|
||||
#if defined CUTEST_UNIX__
|
||||
test_colorize__ = isatty(STDOUT_FILENO);
|
||||
#elif defined CUTEST_WIN__
|
||||
test_colorize__ = _isatty(_fileno(stdout));
|
||||
#else
|
||||
test_colorize__ = 0;
|
||||
#endif
|
||||
|
||||
/* Parse options */
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (seen_double_dash || argv[i][0] != '-') {
|
||||
tests = (const struct test__ **)realloc(
|
||||
(void *)tests, (n + 1) * sizeof(const struct test__ *));
|
||||
if (tests == NULL) {
|
||||
fprintf(stderr, "Out of memory.\n");
|
||||
exit(2);
|
||||
}
|
||||
tests[n] = test_by_name__(argv[i]);
|
||||
if (tests[n] == NULL) {
|
||||
fprintf(stderr, "%s: Unrecognized unit test '%s'\n", argv[0],
|
||||
argv[i]);
|
||||
fprintf(stderr, "Try '%s --list' for list of unit tests.\n",
|
||||
argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
n++;
|
||||
} else if (strcmp(argv[i], "--") == 0) {
|
||||
seen_double_dash = 1;
|
||||
} else if (strcmp(argv[i], "--help") == 0 ||
|
||||
strcmp(argv[i], "-h") == 0) {
|
||||
test_help__();
|
||||
exit(0);
|
||||
} else if (strcmp(argv[i], "--verbose") == 0 ||
|
||||
strcmp(argv[i], "-v") == 0) {
|
||||
test_verbose_level__++;
|
||||
} else if (strncmp(argv[i], "--verbose=", 10) == 0) {
|
||||
test_verbose_level__ = atoi(argv[i] + 10);
|
||||
} else if (strcmp(argv[i], "--color=auto") == 0) {
|
||||
/* noop (set from above) */
|
||||
} else if (strcmp(argv[i], "--color=always") == 0 ||
|
||||
strcmp(argv[i], "--color") == 0) {
|
||||
test_colorize__ = 1;
|
||||
} else if (strcmp(argv[i], "--color=never") == 0) {
|
||||
test_colorize__ = 0;
|
||||
} else if (strcmp(argv[i], "--skip") == 0 ||
|
||||
strcmp(argv[i], "-s") == 0) {
|
||||
test_skip_mode__ = 1;
|
||||
} else if (strcmp(argv[i], "--no-exec") == 0) {
|
||||
test_no_exec__ = 1;
|
||||
} else if (strcmp(argv[i], "--no-summary") == 0) {
|
||||
test_no_summary__ = 1;
|
||||
} else if (strcmp(argv[i], "--list") == 0 ||
|
||||
strcmp(argv[i], "-l") == 0) {
|
||||
test_list_names__();
|
||||
exit(0);
|
||||
} else {
|
||||
fprintf(stderr, "%s: Unrecognized option '%s'\n", argv[0], argv[i]);
|
||||
fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CUTEST_WIN__)
|
||||
SetUnhandledExceptionFilter(test_exception_filter__);
|
||||
#endif
|
||||
|
||||
/* Count all test units */
|
||||
test_count__ = 0;
|
||||
for (i = 0; test_list__[i].func != NULL; i++)
|
||||
test_count__++;
|
||||
|
||||
/* Run the tests */
|
||||
if (n == 0) {
|
||||
/* Run all tests */
|
||||
for (i = 0; test_list__[i].func != NULL; i++)
|
||||
test_run__(&test_list__[i]);
|
||||
} else if (!test_skip_mode__) {
|
||||
/* Run the listed tests */
|
||||
for (i = 0; i < n; i++)
|
||||
test_run__(tests[i]);
|
||||
} else {
|
||||
/* Run all tests except those listed */
|
||||
for (i = 0; test_list__[i].func != NULL; i++) {
|
||||
int want_skip = 0;
|
||||
for (j = 0; j < n; j++) {
|
||||
if (tests[j] == &test_list__[i]) {
|
||||
want_skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!want_skip)
|
||||
test_run__(&test_list__[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write a summary */
|
||||
if (!test_no_summary__ && test_verbose_level__ >= 1) {
|
||||
test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__, "\nSummary:\n");
|
||||
|
||||
if (test_verbose_level__ >= 3) {
|
||||
printf(" Count of all unit tests: %4d\n", test_count__);
|
||||
printf(" Count of run unit tests: %4d\n",
|
||||
test_stat_run_units__);
|
||||
printf(" Count of failed unit tests: %4d\n",
|
||||
test_stat_failed_units__);
|
||||
printf(" Count of skipped unit tests: %4d\n",
|
||||
test_count__ - test_stat_run_units__);
|
||||
}
|
||||
|
||||
if (test_stat_failed_units__ == 0) {
|
||||
test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__,
|
||||
" SUCCESS: All unit tests have passed.\n");
|
||||
} else {
|
||||
test_print_in_color__(
|
||||
CUTEST_COLOR_RED_INTENSIVE__,
|
||||
" FAILED: %d of %d unit tests have failed.\n",
|
||||
test_stat_failed_units__, test_stat_run_units__);
|
||||
}
|
||||
}
|
||||
|
||||
if (tests != NULL)
|
||||
free((void *)tests);
|
||||
|
||||
return (test_stat_failed_units__ == 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
#endif /* #ifndef TEST_NO_MAIN */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef CUTEST_H__ */
|
261
trunk/3rdparty/libsrtp-2-fit/test/dtls_srtp_driver.c
vendored
Normal file
261
trunk/3rdparty/libsrtp-2-fit/test/dtls_srtp_driver.c
vendored
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* dtls_srtp_driver.c
|
||||
*
|
||||
* test driver for DTLS-SRTP functions
|
||||
*
|
||||
* David McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include "getopt_s.h" /* for local getopt() */
|
||||
#include "srtp_priv.h"
|
||||
|
||||
srtp_err_status_t test_dtls_srtp(void);
|
||||
|
||||
srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc);
|
||||
|
||||
void usage(char *prog_name)
|
||||
{
|
||||
printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
|
||||
" -d <mod> turn on debugging module <mod>\n"
|
||||
" -l list debugging modules\n",
|
||||
prog_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned do_list_mods = 0;
|
||||
int q;
|
||||
srtp_err_status_t err;
|
||||
|
||||
printf("dtls_srtp_driver\n");
|
||||
|
||||
/* initialize srtp library */
|
||||
err = srtp_init();
|
||||
if (err) {
|
||||
printf("error: srtp init failed with error code %d\n", err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt_s(argc, argv, "ld:");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
case 'l':
|
||||
do_list_mods = 1;
|
||||
break;
|
||||
case 'd':
|
||||
err = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
|
||||
if (err) {
|
||||
printf("error: set debug module (%s) failed\n", optarg_s);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_list_mods) {
|
||||
err = srtp_crypto_kernel_list_debug_modules();
|
||||
if (err) {
|
||||
printf("error: list of debug modules failed\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
printf("testing dtls_srtp...");
|
||||
err = test_dtls_srtp();
|
||||
if (err) {
|
||||
printf("\nerror (code %d)\n", err);
|
||||
exit(1);
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
/* shut down srtp library */
|
||||
err = srtp_shutdown();
|
||||
if (err) {
|
||||
printf("error: srtp shutdown failed with error code %d\n", err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
srtp_err_status_t test_dtls_srtp(void)
|
||||
{
|
||||
srtp_hdr_t *test_packet;
|
||||
int test_packet_len = 80;
|
||||
srtp_t s;
|
||||
srtp_policy_t policy;
|
||||
uint8_t key[SRTP_MAX_KEY_LEN];
|
||||
uint8_t salt[SRTP_MAX_KEY_LEN];
|
||||
unsigned int key_len, salt_len;
|
||||
srtp_profile_t profile;
|
||||
srtp_err_status_t err;
|
||||
|
||||
memset(&policy, 0x0, sizeof(srtp_policy_t));
|
||||
|
||||
/* create a 'null' SRTP session */
|
||||
err = srtp_create(&s, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* verify that packet-processing functions behave properly - we
|
||||
* expect that these functions will return srtp_err_status_no_ctx
|
||||
*/
|
||||
test_packet = srtp_create_test_packet(80, 0xa5a5a5a5);
|
||||
if (test_packet == NULL)
|
||||
return srtp_err_status_alloc_fail;
|
||||
|
||||
err = srtp_protect(s, test_packet, &test_packet_len);
|
||||
if (err != srtp_err_status_no_ctx) {
|
||||
printf("wrong return value from srtp_protect() (got code %d)\n", err);
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
err = srtp_unprotect(s, test_packet, &test_packet_len);
|
||||
if (err != srtp_err_status_no_ctx) {
|
||||
printf("wrong return value from srtp_unprotect() (got code %d)\n", err);
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
err = srtp_protect_rtcp(s, test_packet, &test_packet_len);
|
||||
if (err != srtp_err_status_no_ctx) {
|
||||
printf("wrong return value from srtp_protect_rtcp() (got code %d)\n",
|
||||
err);
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len);
|
||||
if (err != srtp_err_status_no_ctx) {
|
||||
printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n",
|
||||
err);
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* set keys to known values for testing
|
||||
*/
|
||||
profile = srtp_profile_aes128_cm_sha1_80;
|
||||
key_len = srtp_profile_get_master_key_length(profile);
|
||||
salt_len = srtp_profile_get_master_salt_length(profile);
|
||||
memset(key, 0xff, key_len);
|
||||
memset(salt, 0xee, salt_len);
|
||||
srtp_append_salt_to_key(key, key_len, salt, salt_len);
|
||||
policy.key = key;
|
||||
|
||||
/* initialize SRTP policy from profile */
|
||||
err = srtp_crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile);
|
||||
if (err)
|
||||
return err;
|
||||
err = srtp_crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile);
|
||||
if (err)
|
||||
return err;
|
||||
policy.ssrc.type = ssrc_any_inbound;
|
||||
policy.ekt = NULL;
|
||||
policy.window_size = 128;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.next = NULL;
|
||||
|
||||
err = srtp_add_stream(s, &policy);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = srtp_dealloc(s);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
free(test_packet);
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* srtp_create_test_packet(len, ssrc) returns a pointer to a
|
||||
* (malloced) example RTP packet whose data field has the length given
|
||||
* by pkt_octet_len and the SSRC value ssrc. The total length of the
|
||||
* packet is twelve octets longer, since the header is at the
|
||||
* beginning. There is room at the end of the packet for a trailer,
|
||||
* and the four octets following the packet are filled with 0xff
|
||||
* values to enable testing for overwrites.
|
||||
*
|
||||
* note that the location of the test packet can (and should) be
|
||||
* deallocated with the free() call once it is no longer needed.
|
||||
*/
|
||||
|
||||
srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc)
|
||||
{
|
||||
int i;
|
||||
uint8_t *buffer;
|
||||
srtp_hdr_t *hdr;
|
||||
int bytes_in_hdr = 12;
|
||||
|
||||
/* allocate memory for test packet */
|
||||
hdr = malloc(pkt_octet_len + bytes_in_hdr + SRTP_MAX_TRAILER_LEN + 4);
|
||||
if (!hdr)
|
||||
return NULL;
|
||||
|
||||
hdr->version = 2; /* RTP version two */
|
||||
hdr->p = 0; /* no padding needed */
|
||||
hdr->x = 0; /* no header extension */
|
||||
hdr->cc = 0; /* no CSRCs */
|
||||
hdr->m = 0; /* marker bit */
|
||||
hdr->pt = 0xf; /* payload type */
|
||||
hdr->seq = htons(0x1234); /* sequence number */
|
||||
hdr->ts = htonl(0xdecafbad); /* timestamp */
|
||||
hdr->ssrc = htonl(ssrc); /* synch. source */
|
||||
|
||||
buffer = (uint8_t *)hdr;
|
||||
buffer += bytes_in_hdr;
|
||||
|
||||
/* set RTP data to 0xab */
|
||||
for (i = 0; i < pkt_octet_len; i++)
|
||||
*buffer++ = 0xab;
|
||||
|
||||
/* set post-data value to 0xffff to enable overrun checking */
|
||||
for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++)
|
||||
*buffer++ = 0xff;
|
||||
|
||||
return hdr;
|
||||
}
|
109
trunk/3rdparty/libsrtp-2-fit/test/getopt_s.c
vendored
Normal file
109
trunk/3rdparty/libsrtp-2-fit/test/getopt_s.c
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* getopt.c
|
||||
*
|
||||
* a minimal implementation of the getopt() function, written so that
|
||||
* test applications that use that function can run on non-POSIX
|
||||
* platforms
|
||||
*
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h> /* for NULL */
|
||||
|
||||
int optind_s = 0;
|
||||
|
||||
char *optarg_s;
|
||||
|
||||
#define GETOPT_FOUND_WITHOUT_ARGUMENT 2
|
||||
#define GETOPT_FOUND_WITH_ARGUMENT 1
|
||||
#define GETOPT_NOT_FOUND 0
|
||||
|
||||
static int getopt_check_character(char c, const char *string)
|
||||
{
|
||||
unsigned int max_string_len = 128;
|
||||
|
||||
while (*string != 0) {
|
||||
if (max_string_len == 0) {
|
||||
return GETOPT_NOT_FOUND;
|
||||
}
|
||||
max_string_len--;
|
||||
if (*string++ == c) {
|
||||
if (*string == ':') {
|
||||
return GETOPT_FOUND_WITH_ARGUMENT;
|
||||
} else {
|
||||
return GETOPT_FOUND_WITHOUT_ARGUMENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return GETOPT_NOT_FOUND;
|
||||
}
|
||||
|
||||
int getopt_s(int argc, char *const argv[], const char *optstring)
|
||||
{
|
||||
while (optind_s + 1 < argc) {
|
||||
char *string;
|
||||
|
||||
/* move 'string' on to next argument */
|
||||
optind_s++;
|
||||
string = argv[optind_s];
|
||||
|
||||
if (string == NULL)
|
||||
return '?'; /* NULL argument string */
|
||||
|
||||
if (string[0] != '-')
|
||||
return -1; /* found an unexpected character */
|
||||
|
||||
switch (getopt_check_character(string[1], optstring)) {
|
||||
case GETOPT_FOUND_WITH_ARGUMENT:
|
||||
if (optind_s + 1 < argc) {
|
||||
optind_s++;
|
||||
optarg_s = argv[optind_s];
|
||||
return string[1];
|
||||
} else {
|
||||
return '?'; /* argument missing */
|
||||
}
|
||||
case GETOPT_FOUND_WITHOUT_ARGUMENT:
|
||||
return string[1];
|
||||
case GETOPT_NOT_FOUND:
|
||||
default:
|
||||
return '?'; /* didn't find expected character */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
360
trunk/3rdparty/libsrtp-2-fit/test/rdbx_driver.c
vendored
Normal file
360
trunk/3rdparty/libsrtp-2-fit/test/rdbx_driver.c
vendored
Normal file
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* rdbx_driver.c
|
||||
*
|
||||
* driver for the rdbx implementation (replay database with extended range)
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include "getopt_s.h" /* for local getopt() */
|
||||
|
||||
#include "rdbx.h"
|
||||
#include "cipher_priv.h"
|
||||
|
||||
#ifdef ROC_TEST
|
||||
#error "srtp_rdbx_t won't work with ROC_TEST - bitmask same size as seq_median"
|
||||
#endif
|
||||
|
||||
#include "ut_sim.h"
|
||||
|
||||
srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws);
|
||||
|
||||
double rdbx_check_adds_per_second(int num_trials, unsigned long ws);
|
||||
|
||||
void usage(char *prog_name)
|
||||
{
|
||||
printf("usage: %s [ -t | -v ]\n", prog_name);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
double rate;
|
||||
srtp_err_status_t status;
|
||||
int q;
|
||||
unsigned do_timing_test = 0;
|
||||
unsigned do_validation = 0;
|
||||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt_s(argc, argv, "tv");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
case 't':
|
||||
do_timing_test = 1;
|
||||
break;
|
||||
case 'v':
|
||||
do_validation = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("rdbx (replay database w/ extended range) test driver\n"
|
||||
"David A. McGrew\n"
|
||||
"Cisco Systems, Inc.\n");
|
||||
|
||||
if (!do_validation && !do_timing_test)
|
||||
usage(argv[0]);
|
||||
|
||||
if (do_validation) {
|
||||
printf("testing srtp_rdbx_t (ws=128)...\n");
|
||||
|
||||
status = test_replay_dbx(1 << 12, 128);
|
||||
if (status) {
|
||||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
printf("testing srtp_rdbx_t (ws=1024)...\n");
|
||||
|
||||
status = test_replay_dbx(1 << 12, 1024);
|
||||
if (status) {
|
||||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("passed\n");
|
||||
}
|
||||
|
||||
if (do_timing_test) {
|
||||
rate = rdbx_check_adds_per_second(1 << 18, 128);
|
||||
printf("rdbx_check/replay_adds per second (ws=128): %e\n", rate);
|
||||
rate = rdbx_check_adds_per_second(1 << 18, 1024);
|
||||
printf("rdbx_check/replay_adds per second (ws=1024): %e\n", rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_rdbx(srtp_rdbx_t *rdbx)
|
||||
{
|
||||
char buf[2048];
|
||||
printf("rdbx: {%llu, %s}\n", (unsigned long long)(rdbx->index),
|
||||
bitvector_bit_string(&rdbx->bitmask, buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_check_add(rdbx, idx) checks a known-to-be-good idx against
|
||||
* rdbx, then adds it. if a failure is detected (i.e., the check
|
||||
* indicates that the value is already in rdbx) then
|
||||
* srtp_err_status_algo_fail is returned.
|
||||
*
|
||||
*/
|
||||
|
||||
srtp_err_status_t rdbx_check_add(srtp_rdbx_t *rdbx, uint32_t idx)
|
||||
{
|
||||
int delta;
|
||||
srtp_xtd_seq_num_t est;
|
||||
|
||||
delta = srtp_index_guess(&rdbx->index, &est, idx);
|
||||
|
||||
if (srtp_rdbx_check(rdbx, delta) != srtp_err_status_ok) {
|
||||
printf("replay_check failed at index %u\n", idx);
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* in practice, we'd authenticate the packet containing idx, using
|
||||
* the estimated value est, at this point
|
||||
*/
|
||||
|
||||
if (srtp_rdbx_add_index(rdbx, delta) != srtp_err_status_ok) {
|
||||
printf("rdbx_add_index failed at index %u\n", idx);
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_check_expect_failure(srtp_rdbx_t *rdbx, uint32_t idx)
|
||||
*
|
||||
* checks that a sequence number idx is in the replay database
|
||||
* and thus will be rejected
|
||||
*/
|
||||
|
||||
srtp_err_status_t rdbx_check_expect_failure(srtp_rdbx_t *rdbx, uint32_t idx)
|
||||
{
|
||||
int delta;
|
||||
srtp_xtd_seq_num_t est;
|
||||
srtp_err_status_t status;
|
||||
|
||||
delta = srtp_index_guess(&rdbx->index, &est, idx);
|
||||
|
||||
status = srtp_rdbx_check(rdbx, delta);
|
||||
if (status == srtp_err_status_ok) {
|
||||
printf("delta: %d ", delta);
|
||||
printf("replay_check failed at index %u (false positive)\n", idx);
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
srtp_err_status_t rdbx_check_add_unordered(srtp_rdbx_t *rdbx, uint32_t idx)
|
||||
{
|
||||
int delta;
|
||||
srtp_xtd_seq_num_t est;
|
||||
srtp_err_status_t rstat;
|
||||
|
||||
delta = srtp_index_guess(&rdbx->index, &est, idx);
|
||||
|
||||
rstat = srtp_rdbx_check(rdbx, delta);
|
||||
if ((rstat != srtp_err_status_ok) &&
|
||||
(rstat != srtp_err_status_replay_old)) {
|
||||
printf("replay_check_add_unordered failed at index %u\n", idx);
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
if (rstat == srtp_err_status_replay_old) {
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
if (srtp_rdbx_add_index(rdbx, delta) != srtp_err_status_ok) {
|
||||
printf("rdbx_add_index failed at index %u\n", idx);
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws)
|
||||
{
|
||||
srtp_rdbx_t rdbx;
|
||||
uint32_t idx, ircvd;
|
||||
ut_connection utc;
|
||||
srtp_err_status_t status;
|
||||
int num_fp_trials;
|
||||
|
||||
status = srtp_rdbx_init(&rdbx, ws);
|
||||
if (status) {
|
||||
printf("replay_init failed with error code %d\n", status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* test sequential insertion
|
||||
*/
|
||||
printf("\ttesting sequential insertion...");
|
||||
for (idx = 0; (int)idx < num_trials; idx++) {
|
||||
status = rdbx_check_add(&rdbx, idx);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
/*
|
||||
* test for false positives by checking all of the index
|
||||
* values which we've just added
|
||||
*
|
||||
* note that we limit the number of trials here, since allowing the
|
||||
* rollover counter to roll over would defeat this test
|
||||
*/
|
||||
num_fp_trials = num_trials % 0x10000;
|
||||
if (num_fp_trials == 0) {
|
||||
printf("warning: no false positive tests performed\n");
|
||||
}
|
||||
printf("\ttesting for false positives...");
|
||||
for (idx = 0; (int)idx < num_fp_trials; idx++) {
|
||||
status = rdbx_check_expect_failure(&rdbx, idx);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
/* re-initialize */
|
||||
srtp_rdbx_dealloc(&rdbx);
|
||||
|
||||
if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
|
||||
printf("replay_init failed\n");
|
||||
return srtp_err_status_init_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* test non-sequential insertion
|
||||
*
|
||||
* this test covers only fase negatives, since the values returned
|
||||
* by ut_next_index(...) are distinct
|
||||
*/
|
||||
ut_init(&utc);
|
||||
|
||||
printf("\ttesting non-sequential insertion...");
|
||||
for (idx = 0; (int)idx < num_trials; idx++) {
|
||||
ircvd = ut_next_index(&utc);
|
||||
status = rdbx_check_add_unordered(&rdbx, ircvd);
|
||||
if (status)
|
||||
return status;
|
||||
status = rdbx_check_expect_failure(&rdbx, ircvd);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
/* re-initialize */
|
||||
srtp_rdbx_dealloc(&rdbx);
|
||||
|
||||
if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
|
||||
printf("replay_init failed\n");
|
||||
return srtp_err_status_init_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* test insertion with large gaps.
|
||||
* check for false positives for each insertion.
|
||||
*/
|
||||
printf("\ttesting insertion with large gaps...");
|
||||
for (idx = 0, ircvd = 0; (int)idx < num_trials;
|
||||
idx++, ircvd += (1 << (srtp_cipher_rand_u32_for_tests() % 12))) {
|
||||
status = rdbx_check_add(&rdbx, ircvd);
|
||||
if (status)
|
||||
return status;
|
||||
status = rdbx_check_expect_failure(&rdbx, ircvd);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
srtp_rdbx_dealloc(&rdbx);
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
#include <time.h> /* for clock() */
|
||||
|
||||
double rdbx_check_adds_per_second(int num_trials, unsigned long ws)
|
||||
{
|
||||
uint32_t i;
|
||||
int delta;
|
||||
srtp_rdbx_t rdbx;
|
||||
srtp_xtd_seq_num_t est;
|
||||
clock_t timer;
|
||||
int failures; /* count number of failures */
|
||||
|
||||
if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
|
||||
printf("replay_init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
failures = 0;
|
||||
timer = clock();
|
||||
for (i = 0; (int)i < num_trials; i++) {
|
||||
delta = srtp_index_guess(&rdbx.index, &est, i);
|
||||
|
||||
if (srtp_rdbx_check(&rdbx, delta) != srtp_err_status_ok)
|
||||
++failures;
|
||||
else if (srtp_rdbx_add_index(&rdbx, delta) != srtp_err_status_ok)
|
||||
++failures;
|
||||
}
|
||||
timer = clock() - timer;
|
||||
if (timer < 1) {
|
||||
timer = 1;
|
||||
}
|
||||
|
||||
printf("number of failures: %d \n", failures);
|
||||
|
||||
srtp_rdbx_dealloc(&rdbx);
|
||||
|
||||
return (double)CLOCKS_PER_SEC * num_trials / timer;
|
||||
}
|
285
trunk/3rdparty/libsrtp-2-fit/test/replay_driver.c
vendored
Normal file
285
trunk/3rdparty/libsrtp-2-fit/test/replay_driver.c
vendored
Normal file
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* replay_driver.c
|
||||
*
|
||||
* A driver for the replay_database implementation
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "rdb.h"
|
||||
#include "ut_sim.h"
|
||||
|
||||
#include "cipher_priv.h"
|
||||
|
||||
/*
|
||||
* num_trials defines the number of trials that are used in the
|
||||
* validation functions below
|
||||
*/
|
||||
|
||||
unsigned num_trials = 1 << 16;
|
||||
|
||||
srtp_err_status_t test_rdb_db(void);
|
||||
|
||||
double rdb_check_adds_per_second(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
srtp_err_status_t err;
|
||||
|
||||
printf("testing anti-replay database (srtp_rdb_t)...\n");
|
||||
err = test_rdb_db();
|
||||
if (err) {
|
||||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("done\n");
|
||||
|
||||
printf("rdb_check/rdb_adds per second: %e\n", rdb_check_adds_per_second());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_rdb(srtp_rdb_t *rdb)
|
||||
{
|
||||
printf("rdb: {%u, %s}\n", rdb->window_start,
|
||||
v128_bit_string(&rdb->bitmask));
|
||||
}
|
||||
|
||||
srtp_err_status_t rdb_check_add(srtp_rdb_t *rdb, uint32_t idx)
|
||||
{
|
||||
if (srtp_rdb_check(rdb, idx) != srtp_err_status_ok) {
|
||||
printf("rdb_check failed at index %u\n", idx);
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
|
||||
printf("rdb_add_index failed at index %u\n", idx);
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
srtp_err_status_t rdb_check_expect_failure(srtp_rdb_t *rdb, uint32_t idx)
|
||||
{
|
||||
srtp_err_status_t err;
|
||||
|
||||
err = srtp_rdb_check(rdb, idx);
|
||||
if ((err != srtp_err_status_replay_old) &&
|
||||
(err != srtp_err_status_replay_fail)) {
|
||||
printf("rdb_check failed at index %u (false positive)\n", idx);
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
srtp_err_status_t rdb_check_add_unordered(srtp_rdb_t *rdb, uint32_t idx)
|
||||
{
|
||||
srtp_err_status_t rstat;
|
||||
|
||||
/* printf("index: %u\n", idx); */
|
||||
rstat = srtp_rdb_check(rdb, idx);
|
||||
if ((rstat != srtp_err_status_ok) &&
|
||||
(rstat != srtp_err_status_replay_old)) {
|
||||
printf("rdb_check_add_unordered failed at index %u\n", idx);
|
||||
return rstat;
|
||||
}
|
||||
if (rstat == srtp_err_status_replay_old) {
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
|
||||
printf("rdb_add_index failed at index %u\n", idx);
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
srtp_err_status_t test_rdb_db()
|
||||
{
|
||||
srtp_rdb_t rdb;
|
||||
uint32_t idx, ircvd;
|
||||
ut_connection utc;
|
||||
srtp_err_status_t err;
|
||||
|
||||
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
return srtp_err_status_init_fail;
|
||||
}
|
||||
|
||||
/* test sequential insertion */
|
||||
for (idx = 0; idx < num_trials; idx++) {
|
||||
err = rdb_check_add(&rdb, idx);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* test for false positives */
|
||||
for (idx = 0; idx < num_trials; idx++) {
|
||||
err = rdb_check_expect_failure(&rdb, idx);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* re-initialize */
|
||||
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
/* test non-sequential insertion */
|
||||
ut_init(&utc);
|
||||
|
||||
for (idx = 0; idx < num_trials; idx++) {
|
||||
ircvd = ut_next_index(&utc);
|
||||
err = rdb_check_add_unordered(&rdb, ircvd);
|
||||
if (err)
|
||||
return err;
|
||||
err = rdb_check_expect_failure(&rdb, ircvd);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* re-initialize */
|
||||
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
/* test insertion with large gaps */
|
||||
for (idx = 0, ircvd = 0; idx < num_trials;
|
||||
idx++, ircvd += (1 << (srtp_cipher_rand_u32_for_tests() % 10))) {
|
||||
err = rdb_check_add(&rdb, ircvd);
|
||||
if (err)
|
||||
return err;
|
||||
err = rdb_check_expect_failure(&rdb, ircvd);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* re-initialize */
|
||||
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
/* test loss of first 513 packets */
|
||||
for (idx = 0; idx < num_trials; idx++) {
|
||||
err = rdb_check_add(&rdb, idx + 513);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* test for false positives */
|
||||
for (idx = 0; idx < num_trials + 513; idx++) {
|
||||
err = rdb_check_expect_failure(&rdb, idx);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* test for key expired */
|
||||
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
rdb.window_start = 0x7ffffffe;
|
||||
if (srtp_rdb_increment(&rdb) != srtp_err_status_ok) {
|
||||
printf("srtp_rdb_increment of 0x7ffffffe failed\n");
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
|
||||
printf("rdb valiue was not 0x7fffffff\n");
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
if (srtp_rdb_increment(&rdb) != srtp_err_status_key_expired) {
|
||||
printf("srtp_rdb_increment of 0x7fffffff did not return "
|
||||
"srtp_err_status_key_expired\n");
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
|
||||
printf("rdb valiue was not 0x7fffffff\n");
|
||||
return srtp_err_status_fail;
|
||||
}
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
#include <time.h> /* for clock() */
|
||||
#include <stdlib.h> /* for random() */
|
||||
|
||||
#define REPLAY_NUM_TRIALS 10000000
|
||||
|
||||
double rdb_check_adds_per_second(void)
|
||||
{
|
||||
uint32_t i;
|
||||
srtp_rdb_t rdb;
|
||||
clock_t timer;
|
||||
int failures = 0; /* count number of failures */
|
||||
|
||||
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
timer = clock();
|
||||
for (i = 0; i < REPLAY_NUM_TRIALS; i += 3) {
|
||||
if (srtp_rdb_check(&rdb, i + 2) != srtp_err_status_ok)
|
||||
++failures;
|
||||
if (srtp_rdb_add_index(&rdb, i + 2) != srtp_err_status_ok)
|
||||
++failures;
|
||||
if (srtp_rdb_check(&rdb, i + 1) != srtp_err_status_ok)
|
||||
++failures;
|
||||
if (srtp_rdb_add_index(&rdb, i + 1) != srtp_err_status_ok)
|
||||
++failures;
|
||||
if (srtp_rdb_check(&rdb, i) != srtp_err_status_ok)
|
||||
++failures;
|
||||
if (srtp_rdb_add_index(&rdb, i) != srtp_err_status_ok)
|
||||
++failures;
|
||||
}
|
||||
timer = clock() - timer;
|
||||
|
||||
return (double)CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer;
|
||||
}
|
170
trunk/3rdparty/libsrtp-2-fit/test/roc_driver.c
vendored
Normal file
170
trunk/3rdparty/libsrtp-2-fit/test/roc_driver.c
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* roc_driver.c
|
||||
*
|
||||
* test driver for rollover counter replay implementation
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* defining ROC_TEST causes small datatypes to be used in
|
||||
* srtp_xtd_seq_num_t - this allows the functions to be exhaustively tested.
|
||||
*/
|
||||
#if ROC_NEEDS_TO_BE_TESTED
|
||||
#define ROC_TEST
|
||||
#endif
|
||||
|
||||
#include "rdbx.h"
|
||||
#include "ut_sim.h"
|
||||
|
||||
srtp_err_status_t roc_test(int num_trials);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
srtp_err_status_t status;
|
||||
|
||||
printf("rollover counter test driver\n"
|
||||
"David A. McGrew\n"
|
||||
"Cisco Systems, Inc.\n");
|
||||
|
||||
printf("testing index functions...");
|
||||
status = roc_test(1 << 18);
|
||||
if (status) {
|
||||
printf("failed\n");
|
||||
exit(status);
|
||||
}
|
||||
printf("passed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ROC_VERBOSE 0
|
||||
|
||||
srtp_err_status_t roc_test(int num_trials)
|
||||
{
|
||||
srtp_xtd_seq_num_t local, est, ref;
|
||||
ut_connection utc;
|
||||
int i, num_bad_est = 0;
|
||||
int delta;
|
||||
uint32_t ircvd;
|
||||
double failure_rate;
|
||||
|
||||
srtp_index_init(&local);
|
||||
srtp_index_init(&ref);
|
||||
srtp_index_init(&est);
|
||||
|
||||
printf("\n\ttesting sequential insertion...");
|
||||
for (i = 0; i < 2048; i++) {
|
||||
srtp_index_guess(&local, &est, (uint16_t)ref);
|
||||
#if ROC_VERBOSE
|
||||
printf("%lld, %lld, %d\n", ref, est, i);
|
||||
#endif
|
||||
if (ref != est) {
|
||||
#if ROC_VERBOSE
|
||||
printf(" *bad estimate*\n");
|
||||
#endif
|
||||
++num_bad_est;
|
||||
}
|
||||
srtp_index_advance(&ref, 1);
|
||||
}
|
||||
failure_rate = (double)num_bad_est / num_trials;
|
||||
if (failure_rate > 0.01) {
|
||||
printf("error: failure rate too high (%d bad estimates in %d trials)\n",
|
||||
num_bad_est, num_trials);
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
printf("done\n");
|
||||
|
||||
printf("\ttesting non-sequential insertion...");
|
||||
srtp_index_init(&local);
|
||||
srtp_index_init(&ref);
|
||||
srtp_index_init(&est);
|
||||
ut_init(&utc);
|
||||
|
||||
for (i = 0; i < num_trials; i++) {
|
||||
/* get next seq num from unreliable transport simulator */
|
||||
ircvd = ut_next_index(&utc);
|
||||
|
||||
/* set ref to value of ircvd */
|
||||
ref = ircvd;
|
||||
|
||||
/* estimate index based on low bits of ircvd */
|
||||
delta = srtp_index_guess(&local, &est, (uint16_t)ref);
|
||||
#if ROC_VERBOSE
|
||||
printf("ref: %lld, local: %lld, est: %lld, ircvd: %d, delta: %d\n", ref,
|
||||
local, est, ircvd, delta);
|
||||
#endif
|
||||
|
||||
if (local + delta != est) {
|
||||
printf(" *bad delta*: local %llu + delta %d != est %llu\n",
|
||||
(unsigned long long)local, delta, (unsigned long long)est);
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
|
||||
/* now update local srtp_xtd_seq_num_t as necessary */
|
||||
if (delta > 0)
|
||||
srtp_index_advance(&local, delta);
|
||||
|
||||
if (ref != est) {
|
||||
#if ROC_VERBOSE
|
||||
printf(" *bad estimate*\n");
|
||||
#endif
|
||||
/* record failure event */
|
||||
++num_bad_est;
|
||||
|
||||
/* reset local value to correct value */
|
||||
local = ref;
|
||||
}
|
||||
}
|
||||
failure_rate = (double)num_bad_est / num_trials;
|
||||
if (failure_rate > 0.01) {
|
||||
printf("error: failure rate too high (%d bad estimates in %d trials)\n",
|
||||
num_bad_est, num_trials);
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
printf("done\n");
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
229
trunk/3rdparty/libsrtp-2-fit/test/rtp.c
vendored
Normal file
229
trunk/3rdparty/libsrtp-2-fit/test/rtp.c
vendored
Normal file
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* rtp.c
|
||||
*
|
||||
* library functions for the real-time transport protocol
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "rtp.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "cipher_priv.h"
|
||||
|
||||
#define PRINT_DEBUG 0 /* set to 1 to print out debugging data */
|
||||
#define VERBOSE_DEBUG 0 /* set to 1 to print out more data */
|
||||
|
||||
int rtp_sendto(rtp_sender_t sender, const void *msg, int len)
|
||||
{
|
||||
int octets_sent;
|
||||
srtp_err_status_t stat;
|
||||
int pkt_len = len + RTP_HEADER_LEN;
|
||||
|
||||
/* marshal data */
|
||||
strncpy(sender->message.body, msg, len);
|
||||
|
||||
/* update header */
|
||||
sender->message.header.seq = ntohs(sender->message.header.seq) + 1;
|
||||
sender->message.header.seq = htons(sender->message.header.seq);
|
||||
sender->message.header.ts = ntohl(sender->message.header.ts) + 1;
|
||||
sender->message.header.ts = htonl(sender->message.header.ts);
|
||||
|
||||
/* apply srtp */
|
||||
stat = srtp_protect(sender->srtp_ctx, &sender->message.header, &pkt_len);
|
||||
if (stat) {
|
||||
#if PRINT_DEBUG
|
||||
fprintf(stderr, "error: srtp protection failed with code %d\n", stat);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#if VERBOSE_DEBUG
|
||||
srtp_print_packet(&sender->message.header, pkt_len);
|
||||
#endif
|
||||
octets_sent =
|
||||
sendto(sender->socket, (void *)&sender->message, pkt_len, 0,
|
||||
(struct sockaddr *)&sender->addr, sizeof(struct sockaddr_in));
|
||||
|
||||
if (octets_sent != pkt_len) {
|
||||
#if PRINT_DEBUG
|
||||
fprintf(stderr, "error: couldn't send message %s", (char *)msg);
|
||||
perror("");
|
||||
#endif
|
||||
}
|
||||
|
||||
return octets_sent;
|
||||
}
|
||||
|
||||
int rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len)
|
||||
{
|
||||
int octets_recvd;
|
||||
srtp_err_status_t stat;
|
||||
|
||||
octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message, *len,
|
||||
0, (struct sockaddr *)NULL, 0);
|
||||
|
||||
if (octets_recvd == -1) {
|
||||
*len = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* verify rtp header */
|
||||
if (receiver->message.header.version != 2) {
|
||||
*len = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if PRINT_DEBUG
|
||||
fprintf(stderr, "%d octets received from SSRC %u\n", octets_recvd,
|
||||
receiver->message.header.ssrc);
|
||||
#endif
|
||||
#if VERBOSE_DEBUG
|
||||
srtp_print_packet(&receiver->message.header, octets_recvd);
|
||||
#endif
|
||||
|
||||
/* apply srtp */
|
||||
stat = srtp_unprotect(receiver->srtp_ctx, &receiver->message.header,
|
||||
&octets_recvd);
|
||||
if (stat) {
|
||||
fprintf(stderr, "error: srtp unprotection failed with code %d%s\n",
|
||||
stat,
|
||||
stat == srtp_err_status_replay_fail
|
||||
? " (replay check failed)"
|
||||
: stat == srtp_err_status_auth_fail ? " (auth check failed)"
|
||||
: "");
|
||||
return -1;
|
||||
}
|
||||
strncpy(msg, receiver->message.body, octets_recvd);
|
||||
|
||||
return octets_recvd;
|
||||
}
|
||||
|
||||
int rtp_sender_init(rtp_sender_t sender,
|
||||
int sock,
|
||||
struct sockaddr_in addr,
|
||||
unsigned int ssrc)
|
||||
{
|
||||
/* set header values */
|
||||
sender->message.header.ssrc = htonl(ssrc);
|
||||
sender->message.header.ts = 0;
|
||||
sender->message.header.seq = (uint16_t)srtp_cipher_rand_u32_for_tests();
|
||||
sender->message.header.m = 0;
|
||||
sender->message.header.pt = 0x1;
|
||||
sender->message.header.version = 2;
|
||||
sender->message.header.p = 0;
|
||||
sender->message.header.x = 0;
|
||||
sender->message.header.cc = 0;
|
||||
|
||||
/* set other stuff */
|
||||
sender->socket = sock;
|
||||
sender->addr = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtp_receiver_init(rtp_receiver_t rcvr,
|
||||
int sock,
|
||||
struct sockaddr_in addr,
|
||||
unsigned int ssrc)
|
||||
{
|
||||
/* set header values */
|
||||
rcvr->message.header.ssrc = htonl(ssrc);
|
||||
rcvr->message.header.ts = 0;
|
||||
rcvr->message.header.seq = 0;
|
||||
rcvr->message.header.m = 0;
|
||||
rcvr->message.header.pt = 0x1;
|
||||
rcvr->message.header.version = 2;
|
||||
rcvr->message.header.p = 0;
|
||||
rcvr->message.header.x = 0;
|
||||
rcvr->message.header.cc = 0;
|
||||
|
||||
/* set other stuff */
|
||||
rcvr->socket = sock;
|
||||
rcvr->addr = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy)
|
||||
{
|
||||
return srtp_create(&sender->srtp_ctx, policy);
|
||||
}
|
||||
|
||||
int rtp_sender_deinit_srtp(rtp_sender_t sender)
|
||||
{
|
||||
return srtp_dealloc(sender->srtp_ctx);
|
||||
}
|
||||
|
||||
int rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy)
|
||||
{
|
||||
return srtp_create(&sender->srtp_ctx, policy);
|
||||
}
|
||||
|
||||
int rtp_receiver_deinit_srtp(rtp_receiver_t sender)
|
||||
{
|
||||
return srtp_dealloc(sender->srtp_ctx);
|
||||
}
|
||||
|
||||
rtp_sender_t rtp_sender_alloc(void)
|
||||
{
|
||||
return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t));
|
||||
}
|
||||
|
||||
void rtp_sender_dealloc(rtp_sender_t rtp_ctx)
|
||||
{
|
||||
free(rtp_ctx);
|
||||
}
|
||||
|
||||
rtp_receiver_t rtp_receiver_alloc(void)
|
||||
{
|
||||
return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t));
|
||||
}
|
||||
|
||||
void rtp_receiver_dealloc(rtp_receiver_t rtp_ctx)
|
||||
{
|
||||
free(rtp_ctx);
|
||||
}
|
155
trunk/3rdparty/libsrtp-2-fit/test/rtp.h
vendored
Normal file
155
trunk/3rdparty/libsrtp-2-fit/test/rtp.h
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* rtp.h
|
||||
*
|
||||
* rtp interface for srtp reference implementation
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*
|
||||
* data types:
|
||||
*
|
||||
* rtp_msg_t an rtp message (the data that goes on the wire)
|
||||
* rtp_sender_t sender side socket and rtp info
|
||||
* rtp_receiver_t receiver side socket and rtp info
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRTP_RTP_H
|
||||
#define SRTP_RTP_H
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#elif defined HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "srtp_priv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RTP_HEADER_LEN indicates the size of an RTP header
|
||||
*/
|
||||
#define RTP_HEADER_LEN 12
|
||||
|
||||
/*
|
||||
* RTP_MAX_BUF_LEN defines the largest RTP packet in the rtp.c implementation
|
||||
*/
|
||||
#define RTP_MAX_BUF_LEN 16384
|
||||
|
||||
typedef srtp_hdr_t rtp_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
srtp_hdr_t header;
|
||||
char body[RTP_MAX_BUF_LEN];
|
||||
} rtp_msg_t;
|
||||
|
||||
typedef struct rtp_sender_ctx_t {
|
||||
rtp_msg_t message;
|
||||
int socket;
|
||||
srtp_ctx_t *srtp_ctx;
|
||||
struct sockaddr_in addr; /* reciever's address */
|
||||
} rtp_sender_ctx_t;
|
||||
|
||||
typedef struct rtp_receiver_ctx_t {
|
||||
rtp_msg_t message;
|
||||
int socket;
|
||||
srtp_ctx_t *srtp_ctx;
|
||||
struct sockaddr_in addr; /* receiver's address */
|
||||
} rtp_receiver_ctx_t;
|
||||
|
||||
typedef struct rtp_sender_ctx_t *rtp_sender_t;
|
||||
|
||||
typedef struct rtp_receiver_ctx_t *rtp_receiver_t;
|
||||
|
||||
int rtp_sendto(rtp_sender_t sender, const void *msg, int len);
|
||||
|
||||
int rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len);
|
||||
|
||||
int rtp_receiver_init(rtp_receiver_t rcvr,
|
||||
int sock,
|
||||
struct sockaddr_in addr,
|
||||
unsigned int ssrc);
|
||||
|
||||
int rtp_sender_init(rtp_sender_t sender,
|
||||
int sock,
|
||||
struct sockaddr_in addr,
|
||||
unsigned int ssrc);
|
||||
|
||||
/*
|
||||
* srtp_sender_init(...) initializes an rtp_sender_t
|
||||
*/
|
||||
|
||||
int srtp_sender_init(
|
||||
rtp_sender_t rtp_ctx, /* structure to be init'ed */
|
||||
struct sockaddr_in name, /* socket name */
|
||||
srtp_sec_serv_t security_services, /* sec. servs. to be used */
|
||||
unsigned char *input_key /* master key/salt in hex */
|
||||
);
|
||||
|
||||
int srtp_receiver_init(
|
||||
rtp_receiver_t rtp_ctx, /* structure to be init'ed */
|
||||
struct sockaddr_in name, /* socket name */
|
||||
srtp_sec_serv_t security_services, /* sec. servs. to be used */
|
||||
unsigned char *input_key /* master key/salt in hex */
|
||||
);
|
||||
|
||||
int rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy);
|
||||
|
||||
int rtp_sender_deinit_srtp(rtp_sender_t sender);
|
||||
|
||||
int rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy);
|
||||
|
||||
int rtp_receiver_deinit_srtp(rtp_receiver_t sender);
|
||||
|
||||
rtp_sender_t rtp_sender_alloc(void);
|
||||
|
||||
void rtp_sender_dealloc(rtp_sender_t rtp_ctx);
|
||||
|
||||
rtp_receiver_t rtp_receiver_alloc(void);
|
||||
|
||||
void rtp_receiver_dealloc(rtp_receiver_t rtp_ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SRTP_RTP_H */
|
785
trunk/3rdparty/libsrtp-2-fit/test/rtp_decoder.c
vendored
Normal file
785
trunk/3rdparty/libsrtp-2-fit/test/rtp_decoder.c
vendored
Normal file
|
@ -0,0 +1,785 @@
|
|||
/*
|
||||
* rtp_decoder.c
|
||||
*
|
||||
* decoder structures and functions for SRTP pcap decoder
|
||||
*
|
||||
* Example:
|
||||
* $ wget --no-check-certificate \
|
||||
* https://raw.githubusercontent.com/gteissier/srtp-decrypt/master/marseillaise-srtp.pcap
|
||||
* $ ./test/rtp_decoder -a -t 10 -e 128 -b \
|
||||
* aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz \
|
||||
* < ~/marseillaise-srtp.pcap \
|
||||
* | text2pcap -t "%M:%S." -u 10000,10000 - - \
|
||||
* > ./marseillaise-rtp.pcap
|
||||
*
|
||||
* There is also a different way of setting up key size and tag size
|
||||
* based upon RFC 4568 crypto suite specification, i.e.:
|
||||
*
|
||||
* $ ./test/rtp_decoder -s AES_CM_128_HMAC_SHA1_80 -b \
|
||||
* aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz ...
|
||||
*
|
||||
* Audio can be extracted using extractaudio utility from the RTPproxy
|
||||
* package:
|
||||
*
|
||||
* $ extractaudio -A ./marseillaise-rtp.pcap ./marseillaise-out.wav
|
||||
*
|
||||
* Bernardo Torres <bernardo@torresautomacao.com.br>
|
||||
*
|
||||
* Some structure and code from https://github.com/gteissier/srtp-decrypt
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include "getopt_s.h" /* for local getopt() */
|
||||
#include <assert.h> /* for assert() */
|
||||
|
||||
#include <pcap.h>
|
||||
#include "rtp_decoder.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifndef timersub
|
||||
#define timersub(a, b, result) \
|
||||
do { \
|
||||
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
|
||||
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
|
||||
if ((result)->tv_usec < 0) { \
|
||||
--(result)->tv_sec; \
|
||||
(result)->tv_usec += 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define MAX_KEY_LEN 96
|
||||
#define MAX_FILTER 256
|
||||
#define MAX_FILE 255
|
||||
|
||||
struct srtp_crypto_suite {
|
||||
const char *can_name;
|
||||
int gcm_on;
|
||||
int key_size;
|
||||
int tag_size;
|
||||
};
|
||||
|
||||
static struct srtp_crypto_suite srtp_crypto_suites[] = {
|
||||
#if 0
|
||||
{.can_name = "F8_128_HMAC_SHA1_32", .gcm_on = 0, .key_size = 128, .tag_size = 4},
|
||||
#endif
|
||||
{.can_name = "AES_CM_128_HMAC_SHA1_32",
|
||||
.gcm_on = 0,
|
||||
.key_size = 128,
|
||||
.tag_size = 4 },
|
||||
{.can_name = "AES_CM_128_HMAC_SHA1_80",
|
||||
.gcm_on = 0,
|
||||
.key_size = 128,
|
||||
.tag_size = 10 },
|
||||
{.can_name = "AES_192_CM_HMAC_SHA1_32",
|
||||
.gcm_on = 0,
|
||||
.key_size = 192,
|
||||
.tag_size = 4 },
|
||||
{.can_name = "AES_192_CM_HMAC_SHA1_80",
|
||||
.gcm_on = 0,
|
||||
.key_size = 192,
|
||||
.tag_size = 10 },
|
||||
{.can_name = "AES_256_CM_HMAC_SHA1_32",
|
||||
.gcm_on = 0,
|
||||
.key_size = 256,
|
||||
.tag_size = 4 },
|
||||
{.can_name = "AES_256_CM_HMAC_SHA1_80",
|
||||
.gcm_on = 0,
|
||||
.key_size = 256,
|
||||
.tag_size = 10 },
|
||||
{.can_name = "AEAD_AES_128_GCM",
|
||||
.gcm_on = 1,
|
||||
.key_size = 128,
|
||||
.tag_size = 16 },
|
||||
{.can_name = "AEAD_AES_256_GCM",
|
||||
.gcm_on = 1,
|
||||
.key_size = 256,
|
||||
.tag_size = 16 },
|
||||
{.can_name = NULL }
|
||||
};
|
||||
|
||||
void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
|
||||
const char *msg,
|
||||
void *data)
|
||||
{
|
||||
char level_char = '?';
|
||||
switch (level) {
|
||||
case srtp_log_level_error:
|
||||
level_char = 'e';
|
||||
break;
|
||||
case srtp_log_level_warning:
|
||||
level_char = 'w';
|
||||
break;
|
||||
case srtp_log_level_info:
|
||||
level_char = 'i';
|
||||
break;
|
||||
case srtp_log_level_debug:
|
||||
level_char = 'd';
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "SRTP-LOG [%c]: %s\n", level_char, msg);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
bpf_u_int32 pcap_net = 0;
|
||||
pcap_t *pcap_handle;
|
||||
#if BEW
|
||||
struct sockaddr_in local;
|
||||
#endif
|
||||
srtp_sec_serv_t sec_servs = sec_serv_none;
|
||||
int c;
|
||||
struct srtp_crypto_suite scs, *i_scsp;
|
||||
scs.key_size = 128;
|
||||
scs.tag_size = 0;
|
||||
int gcm_on = 0;
|
||||
char *input_key = NULL;
|
||||
int b64_input = 0;
|
||||
char key[MAX_KEY_LEN];
|
||||
struct bpf_program fp;
|
||||
char filter_exp[MAX_FILTER] = "";
|
||||
char pcap_file[MAX_FILE] = "-";
|
||||
int rtp_packet_offset = DEFAULT_RTP_OFFSET;
|
||||
rtp_decoder_t dec;
|
||||
srtp_policy_t policy = { { 0 } };
|
||||
rtp_decoder_mode_t mode = mode_rtp;
|
||||
srtp_err_status_t status;
|
||||
int len;
|
||||
int expected_len;
|
||||
int do_list_mods = 0;
|
||||
|
||||
fprintf(stderr, "Using %s [0x%x]\n", srtp_get_version_string(),
|
||||
srtp_get_version());
|
||||
|
||||
/* initialize srtp library */
|
||||
status = srtp_init();
|
||||
if (status) {
|
||||
fprintf(stderr,
|
||||
"error: srtp initialization failed with error code %d\n",
|
||||
status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
status = srtp_install_log_handler(rtp_decoder_srtp_log_handler, NULL);
|
||||
if (status) {
|
||||
fprintf(stderr, "error: install log handler failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* check args */
|
||||
while (1) {
|
||||
c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:m:p:o:");
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
switch (c) {
|
||||
case 'b':
|
||||
b64_input = 1;
|
||||
/* fall thru */
|
||||
case 'k':
|
||||
input_key = optarg_s;
|
||||
break;
|
||||
case 'e':
|
||||
scs.key_size = atoi(optarg_s);
|
||||
if (scs.key_size != 128 && scs.key_size != 192 &&
|
||||
scs.key_size != 256) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"error: encryption key size must be 128, 192 or 256 (%d)\n",
|
||||
scs.key_size);
|
||||
exit(1);
|
||||
}
|
||||
input_key = malloc(scs.key_size);
|
||||
sec_servs |= sec_serv_conf;
|
||||
break;
|
||||
case 't':
|
||||
scs.tag_size = atoi(optarg_s);
|
||||
break;
|
||||
case 'a':
|
||||
sec_servs |= sec_serv_auth;
|
||||
break;
|
||||
case 'g':
|
||||
gcm_on = 1;
|
||||
sec_servs |= sec_serv_auth;
|
||||
break;
|
||||
case 'd':
|
||||
status = srtp_set_debug_module(optarg_s, 1);
|
||||
if (status) {
|
||||
fprintf(stderr, "error: set debug module (%s) failed\n",
|
||||
optarg_s);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
if (strlen(optarg_s) > MAX_FILTER) {
|
||||
fprintf(stderr, "error: filter bigger than %d characters\n",
|
||||
MAX_FILTER);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "Setting filter as %s\n", optarg_s);
|
||||
strcpy(filter_exp, optarg_s);
|
||||
break;
|
||||
case 'l':
|
||||
do_list_mods = 1;
|
||||
break;
|
||||
case 's':
|
||||
for (i_scsp = &srtp_crypto_suites[0]; i_scsp->can_name != NULL;
|
||||
i_scsp++) {
|
||||
if (strcasecmp(i_scsp->can_name, optarg_s) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i_scsp->can_name == NULL) {
|
||||
fprintf(stderr, "Unknown/unsupported crypto suite name %s\n",
|
||||
optarg_s);
|
||||
exit(1);
|
||||
}
|
||||
scs = *i_scsp;
|
||||
input_key = malloc(scs.key_size);
|
||||
sec_servs |= sec_serv_conf | sec_serv_auth;
|
||||
gcm_on = scs.gcm_on;
|
||||
break;
|
||||
case 'm':
|
||||
if (strcasecmp("rtp", optarg_s) == 0) {
|
||||
mode = mode_rtp;
|
||||
} else if (strcasecmp("rtcp", optarg_s) == 0) {
|
||||
mode = mode_rtcp;
|
||||
} else if (strcasecmp("rtcp-mux", optarg_s) == 0) {
|
||||
mode = mode_rtcp_mux;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown/unsupported mode %s\n", optarg_s);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
if (strlen(optarg_s) > MAX_FILE) {
|
||||
fprintf(stderr,
|
||||
"error: pcap file path bigger than %d characters\n",
|
||||
MAX_FILE);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(pcap_file, optarg_s);
|
||||
break;
|
||||
case 'o':
|
||||
rtp_packet_offset = atoi(optarg_s);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (scs.tag_size == 0) {
|
||||
if (gcm_on) {
|
||||
scs.tag_size = 16;
|
||||
} else {
|
||||
scs.tag_size = 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (gcm_on && scs.tag_size != 8 && scs.tag_size != 16) {
|
||||
fprintf(stderr, "error: GCM tag size must be 8 or 16 (%d)\n",
|
||||
scs.tag_size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!gcm_on && scs.tag_size != 4 && scs.tag_size != 10) {
|
||||
fprintf(stderr, "error: non GCM tag size must be 4 or 10 (%d)\n",
|
||||
scs.tag_size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (do_list_mods) {
|
||||
status = srtp_list_debug_modules();
|
||||
if (status) {
|
||||
fprintf(stderr, "error: list of debug modules failed\n");
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
|
||||
/*
|
||||
* a key must be provided if and only if security services have
|
||||
* been requested
|
||||
*/
|
||||
if (input_key == NULL) {
|
||||
fprintf(stderr, "key not provided\n");
|
||||
}
|
||||
if (!sec_servs) {
|
||||
fprintf(stderr, "no secservs\n");
|
||||
}
|
||||
fprintf(stderr, "provided\n");
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
/* report security services selected on the command line */
|
||||
fprintf(stderr, "security services: ");
|
||||
if (sec_servs & sec_serv_conf)
|
||||
fprintf(stderr, "confidentiality ");
|
||||
if (sec_servs & sec_serv_auth)
|
||||
fprintf(stderr, "message authentication");
|
||||
if (sec_servs == sec_serv_none)
|
||||
fprintf(stderr, "none");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* set up the srtp policy and master key */
|
||||
if (sec_servs) {
|
||||
/*
|
||||
* create policy structure, using the default mechanisms but
|
||||
* with only the security services requested on the command line,
|
||||
* using the right SSRC value
|
||||
*/
|
||||
switch (sec_servs) {
|
||||
case sec_serv_conf_and_auth:
|
||||
if (gcm_on) {
|
||||
#ifdef OPENSSL
|
||||
switch (scs.key_size) {
|
||||
case 128:
|
||||
if (scs.tag_size == 16) {
|
||||
srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_128_16_auth(
|
||||
&policy.rtcp);
|
||||
} else {
|
||||
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
|
||||
}
|
||||
break;
|
||||
case 256:
|
||||
if (scs.tag_size == 16) {
|
||||
srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_256_16_auth(
|
||||
&policy.rtcp);
|
||||
} else {
|
||||
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#else
|
||||
fprintf(stderr, "error: GCM mode only supported when using the "
|
||||
"OpenSSL crypto engine.\n");
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
switch (scs.key_size) {
|
||||
case 128:
|
||||
if (scs.tag_size == 4) {
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(
|
||||
&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
|
||||
&policy.rtcp);
|
||||
} else {
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
|
||||
&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
|
||||
&policy.rtcp);
|
||||
}
|
||||
break;
|
||||
case 192:
|
||||
#ifdef OPENSSL
|
||||
if (scs.tag_size == 4) {
|
||||
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(
|
||||
&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
|
||||
&policy.rtcp);
|
||||
} else {
|
||||
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
|
||||
&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
|
||||
&policy.rtcp);
|
||||
}
|
||||
#else
|
||||
fprintf(stderr,
|
||||
"error: AES 192 mode only supported when using the "
|
||||
"OpenSSL crypto engine.\n");
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
break;
|
||||
case 256:
|
||||
if (scs.tag_size == 4) {
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(
|
||||
&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
|
||||
&policy.rtcp);
|
||||
} else {
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
|
||||
&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
|
||||
&policy.rtcp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case sec_serv_conf:
|
||||
if (gcm_on) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"error: GCM mode must always be used with auth enabled\n");
|
||||
return -1;
|
||||
} else {
|
||||
switch (scs.key_size) {
|
||||
case 128:
|
||||
srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
|
||||
&policy.rtcp);
|
||||
break;
|
||||
case 192:
|
||||
#ifdef OPENSSL
|
||||
srtp_crypto_policy_set_aes_cm_192_null_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
|
||||
&policy.rtcp);
|
||||
#else
|
||||
fprintf(stderr,
|
||||
"error: AES 192 mode only supported when using the "
|
||||
"OpenSSL crypto engine.\n");
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
break;
|
||||
case 256:
|
||||
srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
|
||||
&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case sec_serv_auth:
|
||||
if (gcm_on) {
|
||||
#ifdef OPENSSL
|
||||
switch (scs.key_size) {
|
||||
case 128:
|
||||
srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_128_8_only_auth(
|
||||
&policy.rtcp);
|
||||
break;
|
||||
case 256:
|
||||
srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_256_8_only_auth(
|
||||
&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
printf("error: GCM mode only supported when using the OpenSSL "
|
||||
"crypto engine.\n");
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
|
||||
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "error: unknown security service requested\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
policy.key = (uint8_t *)key;
|
||||
policy.ekt = NULL;
|
||||
policy.next = NULL;
|
||||
policy.window_size = 128;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.rtp.sec_serv = sec_servs;
|
||||
policy.rtcp.sec_serv =
|
||||
sec_servs; // sec_serv_none; /* we don't do RTCP anyway */
|
||||
fprintf(stderr, "setting tag len %d\n", scs.tag_size);
|
||||
policy.rtp.auth_tag_len = scs.tag_size;
|
||||
|
||||
if (gcm_on && scs.tag_size != 8) {
|
||||
fprintf(stderr, "set tag len %d\n", scs.tag_size);
|
||||
policy.rtp.auth_tag_len = scs.tag_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* read key from hexadecimal or base64 on command line into an octet
|
||||
* string
|
||||
*/
|
||||
if (b64_input) {
|
||||
int pad;
|
||||
expected_len = policy.rtp.cipher_key_len * 4 / 3;
|
||||
len = base64_string_to_octet_string(key, &pad, input_key,
|
||||
strlen(input_key));
|
||||
} else {
|
||||
expected_len = policy.rtp.cipher_key_len * 2;
|
||||
len = hex_string_to_octet_string(key, input_key, expected_len);
|
||||
}
|
||||
/* check that hex string is the right length */
|
||||
if (len < expected_len) {
|
||||
fprintf(stderr, "error: too few digits in key/salt "
|
||||
"(should be %d digits, found %d)\n",
|
||||
expected_len, len);
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(input_key) > policy.rtp.cipher_key_len * 2) {
|
||||
fprintf(stderr, "error: too many digits in key/salt "
|
||||
"(should be %d hexadecimal digits, found %u)\n",
|
||||
policy.rtp.cipher_key_len * 2, (unsigned)strlen(input_key));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int key_octets = (scs.key_size / 8);
|
||||
int salt_octets = policy.rtp.cipher_key_len - key_octets;
|
||||
fprintf(stderr, "set master key/salt to %s/",
|
||||
octet_string_hex_string(key, key_octets));
|
||||
fprintf(stderr, "%s\n",
|
||||
octet_string_hex_string(key + key_octets, salt_octets));
|
||||
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"error: neither encryption or authentication were selected\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pcap_handle = pcap_open_offline(pcap_file, errbuf);
|
||||
|
||||
if (!pcap_handle) {
|
||||
fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
|
||||
exit(1);
|
||||
}
|
||||
assert(pcap_handle != NULL);
|
||||
if ((pcap_compile(pcap_handle, &fp, filter_exp, 1, pcap_net)) == -1) {
|
||||
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp,
|
||||
pcap_geterr(pcap_handle));
|
||||
return (2);
|
||||
}
|
||||
if (pcap_setfilter(pcap_handle, &fp) == -1) {
|
||||
fprintf(stderr, "couldn't install filter %s: %s\n", filter_exp,
|
||||
pcap_geterr(pcap_handle));
|
||||
return (2);
|
||||
}
|
||||
dec = rtp_decoder_alloc();
|
||||
if (dec == NULL) {
|
||||
fprintf(stderr, "error: malloc() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "Starting decoder\n");
|
||||
if (rtp_decoder_init(dec, policy, mode, rtp_packet_offset)) {
|
||||
fprintf(stderr, "error: init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
|
||||
|
||||
if (dec->mode == mode_rtp || dec->mode == mode_rtcp_mux) {
|
||||
fprintf(stderr, "RTP packets decoded: %d\n", dec->rtp_cnt);
|
||||
}
|
||||
if (dec->mode == mode_rtcp || dec->mode == mode_rtcp_mux) {
|
||||
fprintf(stderr, "RTCP packets decoded: %d\n", dec->rtcp_cnt);
|
||||
}
|
||||
fprintf(stderr, "Packet decode errors: %d\n", dec->error_cnt);
|
||||
|
||||
rtp_decoder_deinit(dec);
|
||||
rtp_decoder_dealloc(dec);
|
||||
|
||||
status = srtp_shutdown();
|
||||
if (status) {
|
||||
fprintf(stderr, "error: srtp shutdown failed with error code %d\n",
|
||||
status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usage(char *string)
|
||||
{
|
||||
fprintf(
|
||||
stderr,
|
||||
"usage: %s [-d <debug>]* [[-k][-b] <key>] [-a][-t][-e] [-s "
|
||||
"<srtp-crypto-suite>] [-m <mode>]\n"
|
||||
"or %s -l\n"
|
||||
"where -a use message authentication\n"
|
||||
" -e <key size> use encryption (use 128 or 256 for key size)\n"
|
||||
" -g Use AES-GCM mode (must be used with -e)\n"
|
||||
" -t <tag size> Tag size to use (in GCM mode use 8 or 16)\n"
|
||||
" -k <key> sets the srtp master key given in hexadecimal\n"
|
||||
" -b <key> sets the srtp master key given in base64\n"
|
||||
" -l list debug modules\n"
|
||||
" -f \"<pcap filter>\" to filter only the desired SRTP packets\n"
|
||||
" -d <debug> turn on debugging for module <debug>\n"
|
||||
" -s \"<srtp-crypto-suite>\" to set both key and tag size based\n"
|
||||
" on RFC4568-style crypto suite specification\n"
|
||||
" -m <mode> set the mode to be one of [rtp]|rtcp|rtcp-mux\n"
|
||||
" -p <pcap file> path to pcap file (defaults to stdin)\n"
|
||||
" -o byte offset of RTP packet in capture (defaults to 42)\n",
|
||||
string, string);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rtp_decoder_t rtp_decoder_alloc(void)
|
||||
{
|
||||
return (rtp_decoder_t)malloc(sizeof(rtp_decoder_ctx_t));
|
||||
}
|
||||
|
||||
void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx)
|
||||
{
|
||||
free(rtp_ctx);
|
||||
}
|
||||
|
||||
int rtp_decoder_deinit(rtp_decoder_t decoder)
|
||||
{
|
||||
if (decoder->srtp_ctx) {
|
||||
return srtp_dealloc(decoder->srtp_ctx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtp_decoder_init(rtp_decoder_t dcdr,
|
||||
srtp_policy_t policy,
|
||||
rtp_decoder_mode_t mode,
|
||||
int rtp_packet_offset)
|
||||
{
|
||||
dcdr->rtp_offset = rtp_packet_offset;
|
||||
dcdr->srtp_ctx = NULL;
|
||||
dcdr->start_tv.tv_usec = 0;
|
||||
dcdr->start_tv.tv_sec = 0;
|
||||
dcdr->frame_nr = -1;
|
||||
dcdr->error_cnt = 0;
|
||||
dcdr->rtp_cnt = 0;
|
||||
dcdr->rtcp_cnt = 0;
|
||||
dcdr->mode = mode;
|
||||
dcdr->policy = policy;
|
||||
dcdr->policy.ssrc.type = ssrc_any_inbound;
|
||||
|
||||
if (srtp_create(&dcdr->srtp_ctx, &dcdr->policy)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* decodes key as base64
|
||||
*/
|
||||
|
||||
void hexdump(const void *ptr, size_t size)
|
||||
{
|
||||
int i, j;
|
||||
const unsigned char *cptr = ptr;
|
||||
|
||||
for (i = 0; i < size; i += 16) {
|
||||
fprintf(stdout, "%04x ", i);
|
||||
for (j = 0; j < 16 && i + j < size; j++) {
|
||||
fprintf(stdout, "%02x ", cptr[i + j]);
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void rtp_decoder_handle_pkt(u_char *arg,
|
||||
const struct pcap_pkthdr *hdr,
|
||||
const u_char *bytes)
|
||||
{
|
||||
rtp_decoder_t dcdr = (rtp_decoder_t)arg;
|
||||
rtp_msg_t message;
|
||||
int rtp;
|
||||
int pktsize;
|
||||
struct timeval delta;
|
||||
int octets_recvd;
|
||||
srtp_err_status_t status;
|
||||
dcdr->frame_nr++;
|
||||
|
||||
if ((dcdr->start_tv.tv_sec == 0) && (dcdr->start_tv.tv_usec == 0)) {
|
||||
dcdr->start_tv = hdr->ts;
|
||||
}
|
||||
|
||||
if (hdr->caplen < dcdr->rtp_offset) {
|
||||
return;
|
||||
}
|
||||
const void *rtp_packet = bytes + dcdr->rtp_offset;
|
||||
|
||||
memcpy((void *)&message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
|
||||
pktsize = hdr->caplen - dcdr->rtp_offset;
|
||||
octets_recvd = pktsize;
|
||||
|
||||
if (octets_recvd == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dcdr->mode == mode_rtp) {
|
||||
rtp = 1;
|
||||
} else if (dcdr->mode == mode_rtcp) {
|
||||
rtp = 0;
|
||||
} else {
|
||||
rtp = 1;
|
||||
if (octets_recvd >= 2) {
|
||||
/* rfc5761 */
|
||||
u_char payload_type = *(bytes + dcdr->rtp_offset + 1) & 0x7f;
|
||||
rtp = payload_type < 64 || payload_type > 95;
|
||||
}
|
||||
}
|
||||
|
||||
if (rtp) {
|
||||
/* verify rtp header */
|
||||
if (message.header.version != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = srtp_unprotect(dcdr->srtp_ctx, &message, &octets_recvd);
|
||||
if (status) {
|
||||
dcdr->error_cnt++;
|
||||
return;
|
||||
}
|
||||
dcdr->rtp_cnt++;
|
||||
} else {
|
||||
status = srtp_unprotect_rtcp(dcdr->srtp_ctx, &message, &octets_recvd);
|
||||
if (status) {
|
||||
dcdr->error_cnt++;
|
||||
return;
|
||||
}
|
||||
dcdr->rtcp_cnt++;
|
||||
}
|
||||
timersub(&hdr->ts, &dcdr->start_tv, &delta);
|
||||
fprintf(stdout, "%02ld:%02ld.%06ld\n", delta.tv_sec / 60, delta.tv_sec % 60,
|
||||
(long)delta.tv_usec);
|
||||
hexdump(&message, octets_recvd);
|
||||
}
|
||||
|
||||
void rtp_print_error(srtp_err_status_t status, char *message)
|
||||
{
|
||||
// clang-format off
|
||||
fprintf(stderr,
|
||||
"error: %s %d%s\n", message, status,
|
||||
status == srtp_err_status_replay_fail ? " (replay check failed)" :
|
||||
status == srtp_err_status_bad_param ? " (bad param)" :
|
||||
status == srtp_err_status_no_ctx ? " (no context)" :
|
||||
status == srtp_err_status_cipher_fail ? " (cipher failed)" :
|
||||
status == srtp_err_status_key_expired ? " (key expired)" :
|
||||
status == srtp_err_status_auth_fail ? " (auth check failed)" : "");
|
||||
// clang-format on
|
||||
}
|
122
trunk/3rdparty/libsrtp-2-fit/test/rtp_decoder.h
vendored
Normal file
122
trunk/3rdparty/libsrtp-2-fit/test/rtp_decoder.h
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* rtp_decoder.h
|
||||
*
|
||||
* decoder structures and functions for SRTP pcap decoder
|
||||
*
|
||||
* Bernardo Torres <bernardo@torresautomacao.com.br>
|
||||
*
|
||||
* Some structure and code from https://github.com/gteissier/srtp-decrypt
|
||||
*
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RTP_DECODER_H
|
||||
#define RTP_DECODER_H
|
||||
|
||||
#include "srtp_priv.h"
|
||||
#include "rtp.h"
|
||||
|
||||
#define DEFAULT_RTP_OFFSET 42
|
||||
|
||||
typedef enum {
|
||||
mode_rtp = 0,
|
||||
mode_rtcp,
|
||||
mode_rtcp_mux,
|
||||
} rtp_decoder_mode_t;
|
||||
|
||||
typedef struct rtp_decoder_ctx_t {
|
||||
srtp_policy_t policy;
|
||||
srtp_ctx_t *srtp_ctx;
|
||||
rtp_decoder_mode_t mode;
|
||||
int rtp_offset;
|
||||
struct timeval start_tv;
|
||||
int frame_nr;
|
||||
int error_cnt;
|
||||
int rtp_cnt;
|
||||
int rtcp_cnt;
|
||||
} rtp_decoder_ctx_t;
|
||||
|
||||
typedef struct rtp_decoder_ctx_t *rtp_decoder_t;
|
||||
|
||||
/*
|
||||
* error to string
|
||||
*/
|
||||
void rtp_print_error(srtp_err_status_t status, char *message);
|
||||
|
||||
/*
|
||||
* prints the output of a random buffer in hexadecimal
|
||||
*/
|
||||
void hexdump(const void *ptr, size_t size);
|
||||
|
||||
/*
|
||||
* the function usage() prints an error message describing how this
|
||||
* program should be called, then calls exit()
|
||||
*/
|
||||
void usage(char *prog_name);
|
||||
|
||||
/*
|
||||
* transforms base64 key into octet
|
||||
*/
|
||||
char *decode_sdes(char *in, char *out);
|
||||
|
||||
/*
|
||||
* pcap handling
|
||||
*/
|
||||
void rtp_decoder_handle_pkt(u_char *arg,
|
||||
const struct pcap_pkthdr *hdr,
|
||||
const u_char *bytes);
|
||||
|
||||
rtp_decoder_t rtp_decoder_alloc(void);
|
||||
|
||||
void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx);
|
||||
|
||||
int rtp_decoder_init(rtp_decoder_t dcdr,
|
||||
srtp_policy_t policy,
|
||||
rtp_decoder_mode_t mode,
|
||||
int rtp_packet_offset);
|
||||
|
||||
int rtp_decoder_deinit(rtp_decoder_t decoder);
|
||||
|
||||
void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
|
||||
const char *msg,
|
||||
void *data);
|
||||
|
||||
void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
|
||||
const char *msg,
|
||||
void *data);
|
||||
|
||||
#endif /* RTP_DECODER_H */
|
701
trunk/3rdparty/libsrtp-2-fit/test/rtpw.c
vendored
Normal file
701
trunk/3rdparty/libsrtp-2-fit/test/rtpw.c
vendored
Normal file
|
@ -0,0 +1,701 @@
|
|||
/*
|
||||
* rtpw.c
|
||||
*
|
||||
* rtp word sender/receiver
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*
|
||||
* This app is a simple RTP application intended only for testing
|
||||
* libsrtp. It reads one word at a time from words.txt (or
|
||||
* whatever file is specified as DICT_FILE or with -w), and sends one word out
|
||||
* each USEC_RATE microseconds. Secure RTP protections can be
|
||||
* applied. See the usage() function for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt_s.h" /* for local getopt() */
|
||||
|
||||
#include <stdio.h> /* for printf, fprintf */
|
||||
#include <stdlib.h> /* for atoi() */
|
||||
#include <errno.h>
|
||||
#include <signal.h> /* for signal() */
|
||||
|
||||
#include <string.h> /* for strncpy() */
|
||||
#include <time.h> /* for usleep() */
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for close() */
|
||||
#elif defined(_MSC_VER)
|
||||
#include <io.h> /* for _close() */
|
||||
#define close _close
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#elif defined HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define RTPW_USE_WINSOCK2 1
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "srtp.h"
|
||||
#include "rtp.h"
|
||||
#include "util.h"
|
||||
|
||||
#define DICT_FILE "words.txt"
|
||||
#define USEC_RATE (5e5)
|
||||
#define MAX_WORD_LEN 128
|
||||
#define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a))
|
||||
#define MAX_KEY_LEN 96
|
||||
|
||||
#ifndef HAVE_USLEEP
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#define usleep(us) Sleep((us) / 1000)
|
||||
#else
|
||||
#define usleep(us) sleep((us) / 1000000)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the function usage() prints an error message describing how this
|
||||
* program should be called, then calls exit()
|
||||
*/
|
||||
|
||||
void usage(char *prog_name);
|
||||
|
||||
/*
|
||||
* leave_group(...) de-registers from a multicast group
|
||||
*/
|
||||
|
||||
void leave_group(int sock, struct ip_mreq mreq, char *name);
|
||||
|
||||
/*
|
||||
* setup_signal_handler() sets up a signal handler to trigger
|
||||
* cleanups after an interrupt
|
||||
*/
|
||||
int setup_signal_handler(char *name);
|
||||
|
||||
/*
|
||||
* handle_signal(...) handles interrupt signal to trigger cleanups
|
||||
*/
|
||||
|
||||
volatile int interrupted = 0;
|
||||
|
||||
/*
|
||||
* program_type distinguishes the [s]rtp sender and receiver cases
|
||||
*/
|
||||
|
||||
typedef enum { sender, receiver, unknown } program_type;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *dictfile = DICT_FILE;
|
||||
FILE *dict;
|
||||
char word[MAX_WORD_LEN];
|
||||
int sock, ret;
|
||||
struct in_addr rcvr_addr;
|
||||
struct sockaddr_in name;
|
||||
struct ip_mreq mreq;
|
||||
#if BEW
|
||||
struct sockaddr_in local;
|
||||
#endif
|
||||
program_type prog_type = unknown;
|
||||
srtp_sec_serv_t sec_servs = sec_serv_none;
|
||||
unsigned char ttl = 5;
|
||||
int c;
|
||||
int key_size = 128;
|
||||
int tag_size = 8;
|
||||
int gcm_on = 0;
|
||||
char *input_key = NULL;
|
||||
int b64_input = 0;
|
||||
char *address = NULL;
|
||||
char key[MAX_KEY_LEN];
|
||||
unsigned short port = 0;
|
||||
rtp_sender_t snd;
|
||||
srtp_policy_t policy;
|
||||
srtp_err_status_t status;
|
||||
int len;
|
||||
int expected_len;
|
||||
int do_list_mods = 0;
|
||||
uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */
|
||||
#ifdef RTPW_USE_WINSOCK2
|
||||
WORD wVersionRequested = MAKEWORD(2, 0);
|
||||
WSADATA wsaData;
|
||||
|
||||
ret = WSAStartup(wVersionRequested, &wsaData);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "error: WSAStartup() failed: %d\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&policy, 0x0, sizeof(srtp_policy_t));
|
||||
|
||||
printf("Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version());
|
||||
|
||||
if (setup_signal_handler(argv[0]) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* initialize srtp library */
|
||||
status = srtp_init();
|
||||
if (status) {
|
||||
printf("error: srtp initialization failed with error code %d\n",
|
||||
status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* check args */
|
||||
while (1) {
|
||||
c = getopt_s(argc, argv, "b:k:rsgt:ae:ld:w:");
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
switch (c) {
|
||||
case 'b':
|
||||
b64_input = 1;
|
||||
/* fall thru */
|
||||
case 'k':
|
||||
input_key = optarg_s;
|
||||
break;
|
||||
case 'e':
|
||||
key_size = atoi(optarg_s);
|
||||
if (key_size != 128 && key_size != 256) {
|
||||
printf("error: encryption key size must be 128 or 256 (%d)\n",
|
||||
key_size);
|
||||
exit(1);
|
||||
}
|
||||
sec_servs |= sec_serv_conf;
|
||||
break;
|
||||
case 't':
|
||||
tag_size = atoi(optarg_s);
|
||||
if (tag_size != 8 && tag_size != 16) {
|
||||
printf("error: GCM tag size must be 8 or 16 (%d)\n", tag_size);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
sec_servs |= sec_serv_auth;
|
||||
break;
|
||||
case 'g':
|
||||
gcm_on = 1;
|
||||
sec_servs |= sec_serv_auth;
|
||||
break;
|
||||
case 'r':
|
||||
prog_type = receiver;
|
||||
break;
|
||||
case 's':
|
||||
prog_type = sender;
|
||||
break;
|
||||
case 'd':
|
||||
status = srtp_set_debug_module(optarg_s, 1);
|
||||
if (status) {
|
||||
printf("error: set debug module (%s) failed\n", optarg_s);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
do_list_mods = 1;
|
||||
break;
|
||||
case 'w':
|
||||
dictfile = optarg_s;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (prog_type == unknown) {
|
||||
if (do_list_mods) {
|
||||
status = srtp_list_debug_modules();
|
||||
if (status) {
|
||||
printf("error: list of debug modules failed\n");
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
printf("error: neither sender [-s] nor receiver [-r] specified\n");
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
|
||||
/*
|
||||
* a key must be provided if and only if security services have
|
||||
* been requested
|
||||
*/
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (argc != optind_s + 2) {
|
||||
/* wrong number of arguments */
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
/* get address from arg */
|
||||
address = argv[optind_s++];
|
||||
|
||||
/* get port from arg */
|
||||
port = atoi(argv[optind_s++]);
|
||||
|
||||
/* set address */
|
||||
#ifdef HAVE_INET_ATON
|
||||
if (0 == inet_aton(address, &rcvr_addr)) {
|
||||
fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0],
|
||||
address);
|
||||
exit(1);
|
||||
}
|
||||
if (rcvr_addr.s_addr == INADDR_NONE) {
|
||||
fprintf(stderr, "%s: address error", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
rcvr_addr.s_addr = inet_addr(address);
|
||||
if (0xffffffff == rcvr_addr.s_addr) {
|
||||
fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0],
|
||||
address);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* open socket */
|
||||
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock < 0) {
|
||||
int err;
|
||||
#ifdef RTPW_USE_WINSOCK2
|
||||
err = WSAGetLastError();
|
||||
#else
|
||||
err = errno;
|
||||
#endif
|
||||
fprintf(stderr, "%s: couldn't open socket: %d\n", argv[0], err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&name, 0, sizeof(struct sockaddr_in));
|
||||
name.sin_addr = rcvr_addr;
|
||||
name.sin_family = PF_INET;
|
||||
name.sin_port = htons(port);
|
||||
|
||||
if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
|
||||
if (prog_type == sender) {
|
||||
ret = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
|
||||
sizeof(ttl));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "%s: Failed to set TTL for multicast group",
|
||||
argv[0]);
|
||||
perror("");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
mreq.imr_multiaddr.s_addr = rcvr_addr.s_addr;
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq,
|
||||
sizeof(mreq));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "%s: Failed to join multicast group", argv[0]);
|
||||
perror("");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* report security services selected on the command line */
|
||||
printf("security services: ");
|
||||
if (sec_servs & sec_serv_conf)
|
||||
printf("confidentiality ");
|
||||
if (sec_servs & sec_serv_auth)
|
||||
printf("message authentication");
|
||||
if (sec_servs == sec_serv_none)
|
||||
printf("none");
|
||||
printf("\n");
|
||||
|
||||
/* set up the srtp policy and master key */
|
||||
if (sec_servs) {
|
||||
/*
|
||||
* create policy structure, using the default mechanisms but
|
||||
* with only the security services requested on the command line,
|
||||
* using the right SSRC value
|
||||
*/
|
||||
switch (sec_servs) {
|
||||
case sec_serv_conf_and_auth:
|
||||
if (gcm_on) {
|
||||
#ifdef GCM
|
||||
switch (key_size) {
|
||||
case 128:
|
||||
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
|
||||
break;
|
||||
case 256:
|
||||
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
printf("error: GCM mode only supported when using the OpenSSL "
|
||||
"or NSS crypto engine.\n");
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
switch (key_size) {
|
||||
case 128:
|
||||
srtp_crypto_policy_set_rtp_default(&policy.rtp);
|
||||
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
break;
|
||||
case 256:
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
|
||||
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case sec_serv_conf:
|
||||
if (gcm_on) {
|
||||
printf(
|
||||
"error: GCM mode must always be used with auth enabled\n");
|
||||
return -1;
|
||||
} else {
|
||||
switch (key_size) {
|
||||
case 128:
|
||||
srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
break;
|
||||
case 256:
|
||||
srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case sec_serv_auth:
|
||||
if (gcm_on) {
|
||||
#ifdef GCM
|
||||
switch (key_size) {
|
||||
case 128:
|
||||
srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_128_8_only_auth(
|
||||
&policy.rtcp);
|
||||
break;
|
||||
case 256:
|
||||
srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
|
||||
srtp_crypto_policy_set_aes_gcm_256_8_only_auth(
|
||||
&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
printf("error: GCM mode only supported when using the OpenSSL "
|
||||
"crypto engine.\n");
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
|
||||
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("error: unknown security service requested\n");
|
||||
return -1;
|
||||
}
|
||||
policy.ssrc.type = ssrc_specific;
|
||||
policy.ssrc.value = ssrc;
|
||||
policy.key = (uint8_t *)key;
|
||||
policy.ekt = NULL;
|
||||
policy.next = NULL;
|
||||
policy.window_size = 128;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.rtp.sec_serv = sec_servs;
|
||||
policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */
|
||||
|
||||
if (gcm_on && tag_size != 8) {
|
||||
policy.rtp.auth_tag_len = tag_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* read key from hexadecimal or base64 on command line into an octet
|
||||
* string
|
||||
*/
|
||||
if (b64_input) {
|
||||
int pad;
|
||||
expected_len = (policy.rtp.cipher_key_len * 4) / 3;
|
||||
len = base64_string_to_octet_string(key, &pad, input_key,
|
||||
expected_len);
|
||||
if (pad != 0) {
|
||||
fprintf(stderr, "error: padding in base64 unexpected\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
expected_len = policy.rtp.cipher_key_len * 2;
|
||||
len = hex_string_to_octet_string(key, input_key, expected_len);
|
||||
}
|
||||
/* check that hex string is the right length */
|
||||
if (len < expected_len) {
|
||||
fprintf(stderr, "error: too few digits in key/salt "
|
||||
"(should be %d digits, found %d)\n",
|
||||
expected_len, len);
|
||||
exit(1);
|
||||
}
|
||||
if ((int)strlen(input_key) > policy.rtp.cipher_key_len * 2) {
|
||||
fprintf(stderr, "error: too many digits in key/salt "
|
||||
"(should be %d hexadecimal digits, found %u)\n",
|
||||
policy.rtp.cipher_key_len * 2, (unsigned)strlen(input_key));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("set master key/salt to %s/", octet_string_hex_string(key, 16));
|
||||
printf("%s\n", octet_string_hex_string(key + 16, 14));
|
||||
|
||||
} else {
|
||||
/*
|
||||
* we're not providing security services, so set the policy to the
|
||||
* null policy
|
||||
*
|
||||
* Note that this policy does not conform to the SRTP
|
||||
* specification, since RTCP authentication is required. However,
|
||||
* the effect of this policy is to turn off SRTP, so that this
|
||||
* application is now a vanilla-flavored RTP application.
|
||||
*/
|
||||
srtp_crypto_policy_set_null_cipher_hmac_null(&policy.rtp);
|
||||
srtp_crypto_policy_set_null_cipher_hmac_null(&policy.rtcp);
|
||||
policy.key = (uint8_t *)key;
|
||||
policy.ssrc.type = ssrc_specific;
|
||||
policy.ssrc.value = ssrc;
|
||||
policy.window_size = 0;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.ekt = NULL;
|
||||
policy.next = NULL;
|
||||
}
|
||||
|
||||
if (prog_type == sender) {
|
||||
#if BEW
|
||||
/* bind to local socket (to match crypto policy, if need be) */
|
||||
memset(&local, 0, sizeof(struct sockaddr_in));
|
||||
local.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
local.sin_port = htons(port);
|
||||
ret = bind(sock, (struct sockaddr *)&local, sizeof(struct sockaddr_in));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "%s: bind failed\n", argv[0]);
|
||||
perror("");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* BEW */
|
||||
|
||||
/* initialize sender's rtp and srtp contexts */
|
||||
snd = rtp_sender_alloc();
|
||||
if (snd == NULL) {
|
||||
fprintf(stderr, "error: malloc() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
rtp_sender_init(snd, sock, name, ssrc);
|
||||
status = rtp_sender_init_srtp(snd, &policy);
|
||||
if (status) {
|
||||
fprintf(stderr, "error: srtp_create() failed with code %d\n",
|
||||
status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open dictionary */
|
||||
dict = fopen(dictfile, "r");
|
||||
if (dict == NULL) {
|
||||
fprintf(stderr, "%s: couldn't open file %s\n", argv[0], dictfile);
|
||||
if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
|
||||
leave_group(sock, mreq, argv[0]);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read words from dictionary, then send them off */
|
||||
while (!interrupted && fgets(word, MAX_WORD_LEN, dict) != NULL) {
|
||||
len = strlen(word) + 1; /* plus one for null */
|
||||
|
||||
if (len > MAX_WORD_LEN)
|
||||
printf("error: word %s too large to send\n", word);
|
||||
else {
|
||||
rtp_sendto(snd, word, len);
|
||||
printf("sending word: %s", word);
|
||||
}
|
||||
usleep(USEC_RATE);
|
||||
}
|
||||
|
||||
rtp_sender_deinit_srtp(snd);
|
||||
rtp_sender_dealloc(snd);
|
||||
|
||||
fclose(dict);
|
||||
} else { /* prog_type == receiver */
|
||||
rtp_receiver_t rcvr;
|
||||
|
||||
if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) {
|
||||
close(sock);
|
||||
fprintf(stderr, "%s: socket bind error\n", argv[0]);
|
||||
perror(NULL);
|
||||
if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
|
||||
leave_group(sock, mreq, argv[0]);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rcvr = rtp_receiver_alloc();
|
||||
if (rcvr == NULL) {
|
||||
fprintf(stderr, "error: malloc() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
rtp_receiver_init(rcvr, sock, name, ssrc);
|
||||
status = rtp_receiver_init_srtp(rcvr, &policy);
|
||||
if (status) {
|
||||
fprintf(stderr, "error: srtp_create() failed with code %d\n",
|
||||
status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get next word and loop */
|
||||
while (!interrupted) {
|
||||
len = MAX_WORD_LEN;
|
||||
if (rtp_recvfrom(rcvr, word, &len) > -1)
|
||||
printf("\tword: %s\n", word);
|
||||
}
|
||||
|
||||
rtp_receiver_deinit_srtp(rcvr);
|
||||
rtp_receiver_dealloc(rcvr);
|
||||
}
|
||||
|
||||
if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
|
||||
leave_group(sock, mreq, argv[0]);
|
||||
}
|
||||
|
||||
#ifdef RTPW_USE_WINSOCK2
|
||||
ret = closesocket(sock);
|
||||
#else
|
||||
ret = close(sock);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "%s: Failed to close socket", argv[0]);
|
||||
perror("");
|
||||
}
|
||||
|
||||
status = srtp_shutdown();
|
||||
if (status) {
|
||||
printf("error: srtp shutdown failed with error code %d\n", status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef RTPW_USE_WINSOCK2
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usage(char *string)
|
||||
{
|
||||
printf("usage: %s [-d <debug>]* [-k <key> [-a][-e]] "
|
||||
"[-s | -r] dest_ip dest_port\n"
|
||||
"or %s -l\n"
|
||||
"where -a use message authentication\n"
|
||||
" -e <key size> use encryption (use 128 or 256 for key size)\n"
|
||||
" -g Use AES-GCM mode (must be used with -e)\n"
|
||||
" -t <tag size> Tag size to use in GCM mode (use 8 or 16)\n"
|
||||
" -k <key> sets the srtp master key given in hexadecimal\n"
|
||||
" -b <key> sets the srtp master key given in base64\n"
|
||||
" -s act as rtp sender\n"
|
||||
" -r act as rtp receiver\n"
|
||||
" -l list debug modules\n"
|
||||
" -d <debug> turn on debugging for module <debug>\n"
|
||||
" -w <wordsfile> use <wordsfile> for input, rather than %s\n",
|
||||
string, string, DICT_FILE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void leave_group(int sock, struct ip_mreq mreq, char *name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreq,
|
||||
sizeof(mreq));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "%s: Failed to leave multicast group", name);
|
||||
perror("");
|
||||
}
|
||||
}
|
||||
|
||||
void handle_signal(int signum)
|
||||
{
|
||||
interrupted = 1;
|
||||
/* Reset handler explicitly, in case we don't have sigaction() (and signal()
|
||||
has BSD semantics), or we don't have SA_RESETHAND */
|
||||
signal(signum, SIG_DFL);
|
||||
}
|
||||
|
||||
int setup_signal_handler(char *name)
|
||||
{
|
||||
#if HAVE_SIGACTION
|
||||
struct sigaction act;
|
||||
memset(&act, 0, sizeof(act));
|
||||
|
||||
act.sa_handler = handle_signal;
|
||||
sigemptyset(&act.sa_mask);
|
||||
#if defined(SA_RESETHAND)
|
||||
act.sa_flags = SA_RESETHAND;
|
||||
#else
|
||||
act.sa_flags = 0;
|
||||
#endif
|
||||
/* Note that we're not setting SA_RESTART; we want recvfrom to return
|
||||
* EINTR when we signal the receiver. */
|
||||
|
||||
if (sigaction(SIGTERM, &act, NULL) != 0) {
|
||||
fprintf(stderr, "%s: error setting up signal handler", name);
|
||||
perror("");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (signal(SIGTERM, handle_signal) == SIG_ERR) {
|
||||
fprintf(stderr, "%s: error setting up signal handler", name);
|
||||
perror("");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
176
trunk/3rdparty/libsrtp-2-fit/test/rtpw_test.sh
vendored
Executable file
176
trunk/3rdparty/libsrtp-2-fit/test/rtpw_test.sh
vendored
Executable file
|
@ -0,0 +1,176 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# usage: rtpw_test <rtpw_commands>
|
||||
#
|
||||
# tests the rtpw sender and receiver functions
|
||||
#
|
||||
# Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
case $(uname -s) in
|
||||
*CYGWIN*|*MINGW*)
|
||||
EXE=".exe"
|
||||
;;
|
||||
*Linux*)
|
||||
EXE=""
|
||||
export LD_LIBRARY_PATH=$CRYPTO_LIBDIR
|
||||
;;
|
||||
*Darwin*)
|
||||
EXE=""
|
||||
export DYLD_LIBRARY_PATH=$CRYPTO_LIBDIR
|
||||
;;
|
||||
esac
|
||||
|
||||
RTPW=./rtpw$EXE
|
||||
DEST_PORT=9999
|
||||
DURATION=3
|
||||
|
||||
key=Ky7cUDT2GnI0XKWYbXv9AYmqbcLsqzL9mvdN9t/G
|
||||
|
||||
ARGS="-b $key -a -e 128"
|
||||
|
||||
# First, we run "killall" to get rid of all existing rtpw processes.
|
||||
# This step also enables this script to clean up after itself; if this
|
||||
# script is interrupted after the rtpw processes are started but before
|
||||
# they are killed, those processes will linger. Re-running the script
|
||||
# will get rid of them.
|
||||
|
||||
killall rtpw 2>/dev/null
|
||||
|
||||
if test -x $RTPW; then
|
||||
|
||||
echo $0 ": starting rtpw receiver process... "
|
||||
|
||||
$RTPW $* $ARGS -r 0.0.0.0 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting rtpw sender process..."
|
||||
|
||||
$RTPW $* $ARGS -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
wait $receiver_pid 2>/dev/null
|
||||
wait $sender_pid 2>/dev/null
|
||||
|
||||
|
||||
key=033490ba9e82994fc21013395739038992b2edc5034f61a72345ca598d7bfd0189aa6dc2ecab32fd9af74df6dfc6
|
||||
|
||||
ARGS="-k $key -a -e 256"
|
||||
|
||||
echo $0 ": starting rtpw receiver process... "
|
||||
|
||||
$RTPW $* $ARGS -r 0.0.0.0 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting rtpw sender process..."
|
||||
|
||||
$RTPW $* $ARGS -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
wait $receiver_pid 2>/dev/null
|
||||
wait $sender_pid 2>/dev/null
|
||||
|
||||
echo $0 ": done (test passed)"
|
||||
|
||||
else
|
||||
|
||||
echo "error: can't find executable" $RTPW
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
# EOF
|
||||
|
||||
|
260
trunk/3rdparty/libsrtp-2-fit/test/rtpw_test_gcm.sh
vendored
Executable file
260
trunk/3rdparty/libsrtp-2-fit/test/rtpw_test_gcm.sh
vendored
Executable file
|
@ -0,0 +1,260 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# usage: rtpw_test <rtpw_commands>
|
||||
#
|
||||
# tests the rtpw sender and receiver functions
|
||||
#
|
||||
# Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
case $(uname -s) in
|
||||
*CYGWIN*|*MINGW*)
|
||||
EXE=".exe"
|
||||
;;
|
||||
*Linux*)
|
||||
EXE=""
|
||||
export LD_LIBRARY_PATH=$CRYPTO_LIBDIR
|
||||
;;
|
||||
*Darwin*)
|
||||
EXE=""
|
||||
export DYLD_LIBRARY_PATH=$CRYPTO_LIBDIR
|
||||
;;
|
||||
esac
|
||||
|
||||
RTPW=./rtpw$EXE
|
||||
DEST_PORT=9999
|
||||
DURATION=3
|
||||
|
||||
# First, we run "killall" to get rid of all existing rtpw processes.
|
||||
# This step also enables this script to clean up after itself; if this
|
||||
# script is interrupted after the rtpw processes are started but before
|
||||
# they are killed, those processes will linger. Re-running the script
|
||||
# will get rid of them.
|
||||
|
||||
killall rtpw 2>/dev/null
|
||||
|
||||
if test -x $RTPW; then
|
||||
|
||||
GCMARGS128="-k 01234567890123456789012345678901234567890123456789012345 -g -e 128"
|
||||
echo $0 ": starting GCM mode 128-bit rtpw receiver process... "
|
||||
|
||||
exec $RTPW $* $GCMARGS128 -r 127.0.0.1 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting GCM 128-bit rtpw sender process..."
|
||||
|
||||
exec $RTPW $* $GCMARGS128 -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
wait $receiver_pid 2>/dev/null
|
||||
wait $sender_pid 2>/dev/null
|
||||
|
||||
GCMARGS128="-k 01234567890123456789012345678901234567890123456789012345 -g -t 16 -e 128"
|
||||
echo $0 ": starting GCM mode 128-bit (16 byte tag) rtpw receiver process... "
|
||||
|
||||
exec $RTPW $* $GCMARGS128 -r 127.0.0.1 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting GCM 128-bit (16 byte tag) rtpw sender process..."
|
||||
|
||||
exec $RTPW $* $GCMARGS128 -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
wait $receiver_pid 2>/dev/null
|
||||
wait $sender_pid 2>/dev/null
|
||||
|
||||
|
||||
GCMARGS256="-k 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 -g -e 256"
|
||||
echo $0 ": starting GCM mode 256-bit rtpw receiver process... "
|
||||
|
||||
exec $RTPW $* $GCMARGS256 -r 127.0.0.1 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting GCM 256-bit rtpw sender process..."
|
||||
|
||||
exec $RTPW $* $GCMARGS256 -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
wait $receiver_pid 2>/dev/null
|
||||
wait $sender_pid 2>/dev/null
|
||||
|
||||
GCMARGS256="-k a123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 -g -t 16 -e 256"
|
||||
echo $0 ": starting GCM mode 256-bit (16 byte tag) rtpw receiver process... "
|
||||
|
||||
exec $RTPW $* $GCMARGS256 -r 127.0.0.1 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting GCM 256-bit (16 byte tag) rtpw sender process..."
|
||||
|
||||
exec $RTPW $* $GCMARGS256 -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps -e | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
wait $receiver_pid 2>/dev/null
|
||||
wait $sender_pid 2>/dev/null
|
||||
|
||||
echo $0 ": done (test passed)"
|
||||
|
||||
else
|
||||
|
||||
echo "error: can't find executable" $RTPW
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
# EOF
|
||||
|
||||
|
3837
trunk/3rdparty/libsrtp-2-fit/test/srtp_driver.c
vendored
Normal file
3837
trunk/3rdparty/libsrtp-2-fit/test/srtp_driver.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
185
trunk/3rdparty/libsrtp-2-fit/test/test_srtp.c
vendored
Normal file
185
trunk/3rdparty/libsrtp-2-fit/test/test_srtp.c
vendored
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* test_srtp.c
|
||||
*
|
||||
* Unit tests for internal srtp functions
|
||||
*
|
||||
* Cisco Systems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* libSRTP specific.
|
||||
*/
|
||||
#include "../srtp/srtp.c" // Get access to static functions
|
||||
|
||||
/*
|
||||
* Test specific.
|
||||
*/
|
||||
#include "cutest.h"
|
||||
|
||||
/*
|
||||
* Standard library.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Forward declarations for all tests.
|
||||
*/
|
||||
|
||||
void srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output(void);
|
||||
void srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param(void);
|
||||
void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number(void);
|
||||
|
||||
/*
|
||||
* NULL terminated array of tests.
|
||||
* The first item in the array is a char[] which give some information about
|
||||
* what is being tested and is displayed to the user during runtime, the second
|
||||
* item is the test function.
|
||||
*/
|
||||
|
||||
TEST_LIST = { { "srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output()",
|
||||
srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output },
|
||||
{ "srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()",
|
||||
srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param },
|
||||
{ "srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()",
|
||||
srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number },
|
||||
{ NULL } /* End of tests */ };
|
||||
|
||||
/*
|
||||
* Implementation.
|
||||
*/
|
||||
|
||||
void srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output()
|
||||
{
|
||||
// Preconditions
|
||||
srtp_session_keys_t session_keys;
|
||||
v128_t init_vector;
|
||||
srtcp_hdr_t header;
|
||||
uint32_t sequence_num;
|
||||
|
||||
// Postconditions
|
||||
srtp_err_status_t status;
|
||||
const v128_t zero_vector;
|
||||
memset((v128_t *)&zero_vector, 0, sizeof(v128_t));
|
||||
|
||||
// Given
|
||||
memset(&session_keys, 0, sizeof(srtp_session_keys_t));
|
||||
memset(&init_vector, 0, sizeof(v128_t));
|
||||
memset(&header, 0, sizeof(srtcp_hdr_t));
|
||||
sequence_num = 0x0UL;
|
||||
|
||||
// When
|
||||
status = srtp_calc_aead_iv_srtcp(&session_keys, &init_vector, sequence_num,
|
||||
&header);
|
||||
|
||||
// Then
|
||||
TEST_CHECK(status == srtp_err_status_ok);
|
||||
TEST_CHECK(memcmp(&zero_vector, &init_vector, sizeof(v128_t)) == 0);
|
||||
}
|
||||
|
||||
void srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()
|
||||
{
|
||||
// Preconditions
|
||||
srtp_session_keys_t session_keys;
|
||||
v128_t init_vector;
|
||||
srtcp_hdr_t header;
|
||||
uint32_t sequence_num;
|
||||
|
||||
// Postconditions
|
||||
srtp_err_status_t status;
|
||||
|
||||
// Given
|
||||
memset(&session_keys, 0, sizeof(srtp_session_keys_t));
|
||||
memset(&init_vector, 0, sizeof(v128_t));
|
||||
memset(&header, 0, sizeof(srtcp_hdr_t));
|
||||
sequence_num = 0x7FFFFFFFUL + 0x1UL;
|
||||
|
||||
// When
|
||||
status = srtp_calc_aead_iv_srtcp(&session_keys, &init_vector, sequence_num,
|
||||
&header);
|
||||
|
||||
// Then
|
||||
TEST_CHECK(status == srtp_err_status_bad_param);
|
||||
}
|
||||
|
||||
/*
|
||||
* Regression test for issue #256:
|
||||
* Srtcp IV calculation incorrectly masks high bit of sequence number for
|
||||
* little-endian platforms.
|
||||
* Ensure that for each valid sequence number where the most significant bit is
|
||||
* high that we get an expected and unique IV.
|
||||
*/
|
||||
void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()
|
||||
{
|
||||
#define SAMPLE_COUNT (3)
|
||||
// Preconditions
|
||||
// Test each significant bit high in each full byte.
|
||||
srtp_session_keys_t session_keys;
|
||||
srtcp_hdr_t header;
|
||||
v128_t output_iv[SAMPLE_COUNT];
|
||||
uint32_t sequence_num[SAMPLE_COUNT];
|
||||
v128_t final_iv[SAMPLE_COUNT];
|
||||
size_t i = 0;
|
||||
memset(&output_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
|
||||
sequence_num[0] = 0xFF;
|
||||
sequence_num[1] = 0xFF00;
|
||||
sequence_num[2] = 0xFF0000;
|
||||
|
||||
// Postconditions
|
||||
memset(&final_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
|
||||
final_iv[0].v8[11] = 0xFF;
|
||||
final_iv[1].v8[10] = 0xFF;
|
||||
final_iv[2].v8[9] = 0xFF;
|
||||
|
||||
// Given
|
||||
memset(&session_keys, 0, sizeof(srtp_session_keys_t));
|
||||
memset(&header, 0, sizeof(srtcp_hdr_t));
|
||||
|
||||
// When
|
||||
for (i = 0; i < SAMPLE_COUNT; i++) {
|
||||
TEST_CHECK(srtp_calc_aead_iv_srtcp(&session_keys, &output_iv[i],
|
||||
sequence_num[i],
|
||||
&header) == srtp_err_status_ok);
|
||||
}
|
||||
|
||||
// Then all IVs are as expected
|
||||
for (i = 0; i < SAMPLE_COUNT; i++) {
|
||||
TEST_CHECK(memcmp(&final_iv[i], &output_iv[i], sizeof(v128_t)) == 0);
|
||||
}
|
||||
#undef SAMPLE_COUNT
|
||||
}
|
212
trunk/3rdparty/libsrtp-2-fit/test/util.c
vendored
Normal file
212
trunk/3rdparty/libsrtp-2-fit/test/util.c
vendored
Normal file
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* util.c
|
||||
*
|
||||
* Utilities used by the test apps
|
||||
*
|
||||
* John A. Foley
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2014-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* include space for null terminator */
|
||||
char bit_string[MAX_PRINT_STRING_LEN + 1];
|
||||
|
||||
static inline int hex_char_to_nibble(uint8_t c)
|
||||
{
|
||||
switch (c) {
|
||||
case ('0'):
|
||||
return 0x0;
|
||||
case ('1'):
|
||||
return 0x1;
|
||||
case ('2'):
|
||||
return 0x2;
|
||||
case ('3'):
|
||||
return 0x3;
|
||||
case ('4'):
|
||||
return 0x4;
|
||||
case ('5'):
|
||||
return 0x5;
|
||||
case ('6'):
|
||||
return 0x6;
|
||||
case ('7'):
|
||||
return 0x7;
|
||||
case ('8'):
|
||||
return 0x8;
|
||||
case ('9'):
|
||||
return 0x9;
|
||||
case ('a'):
|
||||
return 0xa;
|
||||
case ('A'):
|
||||
return 0xa;
|
||||
case ('b'):
|
||||
return 0xb;
|
||||
case ('B'):
|
||||
return 0xb;
|
||||
case ('c'):
|
||||
return 0xc;
|
||||
case ('C'):
|
||||
return 0xc;
|
||||
case ('d'):
|
||||
return 0xd;
|
||||
case ('D'):
|
||||
return 0xd;
|
||||
case ('e'):
|
||||
return 0xe;
|
||||
case ('E'):
|
||||
return 0xe;
|
||||
case ('f'):
|
||||
return 0xf;
|
||||
case ('F'):
|
||||
return 0xf;
|
||||
default:
|
||||
return -1; /* this flags an error */
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return -1; /* this keeps compilers from complaining */
|
||||
}
|
||||
|
||||
uint8_t nibble_to_hex_char(uint8_t nibble)
|
||||
{
|
||||
char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
return buf[nibble & 0xF];
|
||||
}
|
||||
|
||||
/*
|
||||
* hex_string_to_octet_string converts a hexadecimal string
|
||||
* of length 2 * len to a raw octet string of length len
|
||||
*/
|
||||
int hex_string_to_octet_string(char *raw, char *hex, int len)
|
||||
{
|
||||
uint8_t x;
|
||||
int tmp;
|
||||
int hex_len;
|
||||
|
||||
hex_len = 0;
|
||||
while (hex_len < len) {
|
||||
tmp = hex_char_to_nibble(hex[0]);
|
||||
if (tmp == -1) {
|
||||
return hex_len;
|
||||
}
|
||||
x = (tmp << 4);
|
||||
hex_len++;
|
||||
tmp = hex_char_to_nibble(hex[1]);
|
||||
if (tmp == -1) {
|
||||
return hex_len;
|
||||
}
|
||||
x |= (tmp & 0xff);
|
||||
hex_len++;
|
||||
*raw++ = x;
|
||||
hex += 2;
|
||||
}
|
||||
return hex_len;
|
||||
}
|
||||
|
||||
char *octet_string_hex_string(const void *s, int length)
|
||||
{
|
||||
const uint8_t *str = (const uint8_t *)s;
|
||||
int i;
|
||||
|
||||
/* double length, since one octet takes two hex characters */
|
||||
length *= 2;
|
||||
|
||||
/* truncate string if it would be too long */
|
||||
if (length > MAX_PRINT_STRING_LEN) {
|
||||
length = MAX_PRINT_STRING_LEN;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i += 2) {
|
||||
bit_string[i] = nibble_to_hex_char(*str >> 4);
|
||||
bit_string[i + 1] = nibble_to_hex_char(*str++ & 0xF);
|
||||
}
|
||||
bit_string[i] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static int base64_block_to_octet_triple(char *out, char *in)
|
||||
{
|
||||
unsigned char sextets[4] = { 0 };
|
||||
int j = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
char *p = strchr(b64chars, in[i]);
|
||||
if (p != NULL) {
|
||||
sextets[i] = p - b64chars;
|
||||
} else {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
out[0] = (sextets[0] << 2) | (sextets[1] >> 4);
|
||||
if (j < 2) {
|
||||
out[1] = (sextets[1] << 4) | (sextets[2] >> 2);
|
||||
}
|
||||
if (j < 1) {
|
||||
out[2] = (sextets[2] << 6) | sextets[3];
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
int base64_string_to_octet_string(char *out, int *pad, char *in, int len)
|
||||
{
|
||||
int k = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
if (len % 4 != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (i < len && j == 0) {
|
||||
j = base64_block_to_octet_triple(out + k, in + i);
|
||||
k += 3;
|
||||
i += 4;
|
||||
}
|
||||
*pad = j;
|
||||
return i;
|
||||
}
|
53
trunk/3rdparty/libsrtp-2-fit/test/util.h
vendored
Normal file
53
trunk/3rdparty/libsrtp-2-fit/test/util.h
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* util.h
|
||||
*
|
||||
* Utilities used by the test apps
|
||||
*
|
||||
* John A. Foley
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2014-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef SRTP_TEST_UTIL_H
|
||||
#define SRTP_TEST_UTIL_H
|
||||
|
||||
#define MAX_PRINT_STRING_LEN 1024
|
||||
|
||||
int hex_string_to_octet_string(char *raw, char *hex, int len);
|
||||
char *octet_string_hex_string(const void *s, int length);
|
||||
int base64_string_to_octet_string(char *raw, int *pad, char *base64, int len);
|
||||
|
||||
#endif
|
250
trunk/3rdparty/libsrtp-2-fit/test/words.txt
vendored
Normal file
250
trunk/3rdparty/libsrtp-2-fit/test/words.txt
vendored
Normal file
|
@ -0,0 +1,250 @@
|
|||
abducing
|
||||
acidheads
|
||||
acidness
|
||||
actons
|
||||
admixtures
|
||||
affidavit
|
||||
agelastic
|
||||
alated
|
||||
alimentary
|
||||
alleviated
|
||||
allseed
|
||||
annexure
|
||||
arragonite
|
||||
atonements
|
||||
autacoid
|
||||
axe
|
||||
axon
|
||||
ayres
|
||||
beathing
|
||||
blazonry
|
||||
bottom
|
||||
braising
|
||||
brehon
|
||||
brindisi
|
||||
broadcasts
|
||||
buds
|
||||
bulnbulns
|
||||
bushcraft
|
||||
calamander
|
||||
calipee
|
||||
casing
|
||||
caveat
|
||||
chaffings
|
||||
citifies
|
||||
clappers
|
||||
claques
|
||||
clavate
|
||||
colonial
|
||||
colonials
|
||||
commonalty
|
||||
compares
|
||||
consequent
|
||||
consumed
|
||||
contango
|
||||
courtierly
|
||||
creamery
|
||||
cruddiest
|
||||
cue
|
||||
cultish
|
||||
cumin
|
||||
cyclus
|
||||
dahlias
|
||||
dentitions
|
||||
derailers
|
||||
devitrify
|
||||
dibs
|
||||
diphysite
|
||||
disjunes
|
||||
drolleries
|
||||
dubitated
|
||||
dupion
|
||||
earliness
|
||||
eductor
|
||||
elenctic
|
||||
empresses
|
||||
entames
|
||||
epaulettes
|
||||
epicanthic
|
||||
epochal
|
||||
estated
|
||||
eurhythmic
|
||||
exfoliated
|
||||
extremity
|
||||
fayence
|
||||
figgery
|
||||
flaming
|
||||
foes
|
||||
forelays
|
||||
forewings
|
||||
forfeits
|
||||
fratches
|
||||
gardened
|
||||
gentile
|
||||
glumpish
|
||||
glyph
|
||||
goatherd
|
||||
grow
|
||||
gulden
|
||||
gumming
|
||||
hackling
|
||||
hanapers
|
||||
hared
|
||||
hatters
|
||||
hectare
|
||||
hedger
|
||||
heel
|
||||
heterodox
|
||||
hidden
|
||||
histologic
|
||||
howe
|
||||
inglobe
|
||||
inliers
|
||||
inuredness
|
||||
iotacism
|
||||
japed
|
||||
jelled
|
||||
jiffy
|
||||
jollies
|
||||
judgeship
|
||||
karite
|
||||
kart
|
||||
kenophobia
|
||||
kittens
|
||||
lactarian
|
||||
lancets
|
||||
leasable
|
||||
leep
|
||||
leming
|
||||
licorice
|
||||
listing
|
||||
lividly
|
||||
lobectomy
|
||||
lysosome
|
||||
madders
|
||||
maderizing
|
||||
manacle
|
||||
mangels
|
||||
marshiest
|
||||
maulstick
|
||||
meliorates
|
||||
mercy
|
||||
mikados
|
||||
monarchise
|
||||
moultings
|
||||
mucro
|
||||
munnions
|
||||
mystic
|
||||
myxoedemic
|
||||
nointing
|
||||
nong
|
||||
nonsense
|
||||
ochidore
|
||||
octuor
|
||||
officering
|
||||
opaqued
|
||||
oragious
|
||||
outtell
|
||||
oxeye
|
||||
pads
|
||||
palamae
|
||||
pansophy
|
||||
parazoa
|
||||
pepsines
|
||||
perimetric
|
||||
pheasant
|
||||
phonotypy
|
||||
pitarah
|
||||
plaintful
|
||||
poinders
|
||||
poke
|
||||
politer
|
||||
poonces
|
||||
populism
|
||||
pouty
|
||||
praedial
|
||||
presence
|
||||
prompter
|
||||
pummelled
|
||||
punishing
|
||||
quippish
|
||||
radicality
|
||||
radiuses
|
||||
rebuffing
|
||||
recorded
|
||||
redips
|
||||
regulators
|
||||
replay
|
||||
retrocedes
|
||||
rigors
|
||||
risen
|
||||
rootstocks
|
||||
rotenone
|
||||
rudenesses
|
||||
ruggedest
|
||||
runabout
|
||||
ruthfully
|
||||
sagacious
|
||||
scapes
|
||||
sclera
|
||||
sclerotium
|
||||
scumbering
|
||||
secondi
|
||||
serial
|
||||
shampoo
|
||||
showed
|
||||
sights
|
||||
sirenised
|
||||
sized
|
||||
slave
|
||||
socle
|
||||
solidness
|
||||
some
|
||||
spetches
|
||||
spiels
|
||||
squiring
|
||||
staminode
|
||||
stay
|
||||
stewpot
|
||||
stunsails
|
||||
subhumid
|
||||
subprogram
|
||||
supawn
|
||||
surplusage
|
||||
swimming
|
||||
swineherd
|
||||
tabun
|
||||
talliths
|
||||
taroks
|
||||
tensed
|
||||
thinnings
|
||||
three
|
||||
tipper
|
||||
toko
|
||||
tomahawks
|
||||
tombolos
|
||||
torpefy
|
||||
torulae
|
||||
touns
|
||||
travails
|
||||
tsarist
|
||||
unbeseems
|
||||
unblamably
|
||||
unbooked
|
||||
unnailed
|
||||
updates
|
||||
valorise
|
||||
viability
|
||||
virtue
|
||||
vulturns
|
||||
vulvate
|
||||
warran
|
||||
weakness
|
||||
westernise
|
||||
whingeings
|
||||
wrenching
|
||||
written
|
||||
yak
|
||||
yate
|
||||
yaupon
|
||||
zendiks
|
Loading…
Add table
Add a link
Reference in a new issue