2
0

rtp_decoder.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. /*
  2. * rtp_decoder.c
  3. *
  4. * decoder structures and functions for SRTP pcap decoder
  5. *
  6. * Example:
  7. * $ wget --no-check-certificate \
  8. * https://raw.githubusercontent.com/gteissier/srtp-decrypt/master/marseillaise-srtp.pcap
  9. * $ ./test/rtp_decoder -a -t 10 -e 128 -b \
  10. * aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz \
  11. * < ~/marseillaise-srtp.pcap \
  12. * | text2pcap -t "%M:%S." -u 10000,10000 - - \
  13. * > ./marseillaise-rtp.pcap
  14. *
  15. * There is also a different way of setting up key size and tag size
  16. * based upon RFC 4568 crypto suite specification, i.e.:
  17. *
  18. * $ ./test/rtp_decoder -s AES_CM_128_HMAC_SHA1_80 -b \
  19. * aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz ...
  20. *
  21. * Audio can be extracted using extractaudio utility from the RTPproxy
  22. * package:
  23. *
  24. * $ extractaudio -A ./marseillaise-rtp.pcap ./marseillaise-out.wav
  25. *
  26. * Bernardo Torres <bernardo@torresautomacao.com.br>
  27. *
  28. * Some structure and code from https://github.com/gteissier/srtp-decrypt
  29. */
  30. /*
  31. *
  32. * Copyright (c) 2001-2017 Cisco Systems, Inc.
  33. * All rights reserved.
  34. *
  35. * Redistribution and use in source and binary forms, with or without
  36. * modification, are permitted provided that the following conditions
  37. * are met:
  38. *
  39. * Redistributions of source code must retain the above copyright
  40. * notice, this list of conditions and the following disclaimer.
  41. *
  42. * Redistributions in binary form must reproduce the above
  43. * copyright notice, this list of conditions and the following
  44. * disclaimer in the documentation and/or other materials provided
  45. * with the distribution.
  46. *
  47. * Neither the name of the Cisco Systems, Inc. nor the names of its
  48. * contributors may be used to endorse or promote products derived
  49. * from this software without specific prior written permission.
  50. *
  51. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  52. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  53. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  54. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  55. * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  56. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  57. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  58. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  59. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  60. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  61. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  62. * OF THE POSSIBILITY OF SUCH DAMAGE.
  63. *
  64. */
  65. #include "getopt_s.h" /* for local getopt() */
  66. #include <assert.h> /* for assert() */
  67. #include <pcap.h>
  68. #include "rtp_decoder.h"
  69. #include "util.h"
  70. #ifndef timersub
  71. #define timersub(a, b, result) \
  72. do { \
  73. (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
  74. (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
  75. if ((result)->tv_usec < 0) { \
  76. --(result)->tv_sec; \
  77. (result)->tv_usec += 1000000; \
  78. } \
  79. } while (0)
  80. #endif
  81. #define MAX_KEY_LEN 96
  82. #define MAX_FILTER 256
  83. #define MAX_FILE 255
  84. struct srtp_crypto_suite {
  85. const char *can_name;
  86. int gcm_on;
  87. int key_size;
  88. int tag_size;
  89. };
  90. static struct srtp_crypto_suite srtp_crypto_suites[] = {
  91. #if 0
  92. {.can_name = "F8_128_HMAC_SHA1_32", .gcm_on = 0, .key_size = 128, .tag_size = 4},
  93. #endif
  94. {.can_name = "AES_CM_128_HMAC_SHA1_32",
  95. .gcm_on = 0,
  96. .key_size = 128,
  97. .tag_size = 4 },
  98. {.can_name = "AES_CM_128_HMAC_SHA1_80",
  99. .gcm_on = 0,
  100. .key_size = 128,
  101. .tag_size = 10 },
  102. {.can_name = "AES_192_CM_HMAC_SHA1_32",
  103. .gcm_on = 0,
  104. .key_size = 192,
  105. .tag_size = 4 },
  106. {.can_name = "AES_192_CM_HMAC_SHA1_80",
  107. .gcm_on = 0,
  108. .key_size = 192,
  109. .tag_size = 10 },
  110. {.can_name = "AES_256_CM_HMAC_SHA1_32",
  111. .gcm_on = 0,
  112. .key_size = 256,
  113. .tag_size = 4 },
  114. {.can_name = "AES_256_CM_HMAC_SHA1_80",
  115. .gcm_on = 0,
  116. .key_size = 256,
  117. .tag_size = 10 },
  118. {.can_name = "AEAD_AES_128_GCM",
  119. .gcm_on = 1,
  120. .key_size = 128,
  121. .tag_size = 16 },
  122. {.can_name = "AEAD_AES_256_GCM",
  123. .gcm_on = 1,
  124. .key_size = 256,
  125. .tag_size = 16 },
  126. {.can_name = NULL }
  127. };
  128. void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
  129. const char *msg,
  130. void *data)
  131. {
  132. char level_char = '?';
  133. switch (level) {
  134. case srtp_log_level_error:
  135. level_char = 'e';
  136. break;
  137. case srtp_log_level_warning:
  138. level_char = 'w';
  139. break;
  140. case srtp_log_level_info:
  141. level_char = 'i';
  142. break;
  143. case srtp_log_level_debug:
  144. level_char = 'd';
  145. break;
  146. }
  147. fprintf(stderr, "SRTP-LOG [%c]: %s\n", level_char, msg);
  148. }
  149. int main(int argc, char *argv[])
  150. {
  151. char errbuf[PCAP_ERRBUF_SIZE];
  152. bpf_u_int32 pcap_net = 0;
  153. pcap_t *pcap_handle;
  154. #if BEW
  155. struct sockaddr_in local;
  156. #endif
  157. srtp_sec_serv_t sec_servs = sec_serv_none;
  158. int c;
  159. struct srtp_crypto_suite scs, *i_scsp;
  160. scs.key_size = 128;
  161. scs.tag_size = 0;
  162. int gcm_on = 0;
  163. char *input_key = NULL;
  164. int b64_input = 0;
  165. char key[MAX_KEY_LEN];
  166. struct bpf_program fp;
  167. char filter_exp[MAX_FILTER] = "";
  168. char pcap_file[MAX_FILE] = "-";
  169. int rtp_packet_offset = DEFAULT_RTP_OFFSET;
  170. rtp_decoder_t dec;
  171. srtp_policy_t policy = { { 0 } };
  172. rtp_decoder_mode_t mode = mode_rtp;
  173. srtp_err_status_t status;
  174. int len;
  175. int expected_len;
  176. int do_list_mods = 0;
  177. fprintf(stderr, "Using %s [0x%x]\n", srtp_get_version_string(),
  178. srtp_get_version());
  179. /* initialize srtp library */
  180. status = srtp_init();
  181. if (status) {
  182. fprintf(stderr,
  183. "error: srtp initialization failed with error code %d\n",
  184. status);
  185. exit(1);
  186. }
  187. status = srtp_install_log_handler(rtp_decoder_srtp_log_handler, NULL);
  188. if (status) {
  189. fprintf(stderr, "error: install log handler failed\n");
  190. exit(1);
  191. }
  192. /* check args */
  193. while (1) {
  194. c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:m:p:o:");
  195. if (c == -1) {
  196. break;
  197. }
  198. switch (c) {
  199. case 'b':
  200. b64_input = 1;
  201. /* fall thru */
  202. case 'k':
  203. input_key = optarg_s;
  204. break;
  205. case 'e':
  206. scs.key_size = atoi(optarg_s);
  207. if (scs.key_size != 128 && scs.key_size != 192 &&
  208. scs.key_size != 256) {
  209. fprintf(
  210. stderr,
  211. "error: encryption key size must be 128, 192 or 256 (%d)\n",
  212. scs.key_size);
  213. exit(1);
  214. }
  215. input_key = malloc(scs.key_size);
  216. sec_servs |= sec_serv_conf;
  217. break;
  218. case 't':
  219. scs.tag_size = atoi(optarg_s);
  220. break;
  221. case 'a':
  222. sec_servs |= sec_serv_auth;
  223. break;
  224. case 'g':
  225. gcm_on = 1;
  226. sec_servs |= sec_serv_auth;
  227. break;
  228. case 'd':
  229. status = srtp_set_debug_module(optarg_s, 1);
  230. if (status) {
  231. fprintf(stderr, "error: set debug module (%s) failed\n",
  232. optarg_s);
  233. exit(1);
  234. }
  235. break;
  236. case 'f':
  237. if (strlen(optarg_s) > MAX_FILTER) {
  238. fprintf(stderr, "error: filter bigger than %d characters\n",
  239. MAX_FILTER);
  240. exit(1);
  241. }
  242. fprintf(stderr, "Setting filter as %s\n", optarg_s);
  243. strcpy(filter_exp, optarg_s);
  244. break;
  245. case 'l':
  246. do_list_mods = 1;
  247. break;
  248. case 's':
  249. for (i_scsp = &srtp_crypto_suites[0]; i_scsp->can_name != NULL;
  250. i_scsp++) {
  251. if (strcasecmp(i_scsp->can_name, optarg_s) == 0) {
  252. break;
  253. }
  254. }
  255. if (i_scsp->can_name == NULL) {
  256. fprintf(stderr, "Unknown/unsupported crypto suite name %s\n",
  257. optarg_s);
  258. exit(1);
  259. }
  260. scs = *i_scsp;
  261. input_key = malloc(scs.key_size);
  262. sec_servs |= sec_serv_conf | sec_serv_auth;
  263. gcm_on = scs.gcm_on;
  264. break;
  265. case 'm':
  266. if (strcasecmp("rtp", optarg_s) == 0) {
  267. mode = mode_rtp;
  268. } else if (strcasecmp("rtcp", optarg_s) == 0) {
  269. mode = mode_rtcp;
  270. } else if (strcasecmp("rtcp-mux", optarg_s) == 0) {
  271. mode = mode_rtcp_mux;
  272. } else {
  273. fprintf(stderr, "Unknown/unsupported mode %s\n", optarg_s);
  274. exit(1);
  275. }
  276. break;
  277. case 'p':
  278. if (strlen(optarg_s) > MAX_FILE) {
  279. fprintf(stderr,
  280. "error: pcap file path bigger than %d characters\n",
  281. MAX_FILE);
  282. exit(1);
  283. }
  284. strcpy(pcap_file, optarg_s);
  285. break;
  286. case 'o':
  287. rtp_packet_offset = atoi(optarg_s);
  288. break;
  289. default:
  290. usage(argv[0]);
  291. }
  292. }
  293. if (scs.tag_size == 0) {
  294. if (gcm_on) {
  295. scs.tag_size = 16;
  296. } else {
  297. scs.tag_size = 10;
  298. }
  299. }
  300. if (gcm_on && scs.tag_size != 8 && scs.tag_size != 16) {
  301. fprintf(stderr, "error: GCM tag size must be 8 or 16 (%d)\n",
  302. scs.tag_size);
  303. exit(1);
  304. }
  305. if (!gcm_on && scs.tag_size != 4 && scs.tag_size != 10) {
  306. fprintf(stderr, "error: non GCM tag size must be 4 or 10 (%d)\n",
  307. scs.tag_size);
  308. exit(1);
  309. }
  310. if (do_list_mods) {
  311. status = srtp_list_debug_modules();
  312. if (status) {
  313. fprintf(stderr, "error: list of debug modules failed\n");
  314. exit(1);
  315. }
  316. return 0;
  317. }
  318. if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
  319. /*
  320. * a key must be provided if and only if security services have
  321. * been requested
  322. */
  323. if (input_key == NULL) {
  324. fprintf(stderr, "key not provided\n");
  325. }
  326. if (!sec_servs) {
  327. fprintf(stderr, "no secservs\n");
  328. }
  329. fprintf(stderr, "provided\n");
  330. usage(argv[0]);
  331. }
  332. /* report security services selected on the command line */
  333. fprintf(stderr, "security services: ");
  334. if (sec_servs & sec_serv_conf)
  335. fprintf(stderr, "confidentiality ");
  336. if (sec_servs & sec_serv_auth)
  337. fprintf(stderr, "message authentication");
  338. if (sec_servs == sec_serv_none)
  339. fprintf(stderr, "none");
  340. fprintf(stderr, "\n");
  341. /* set up the srtp policy and master key */
  342. if (sec_servs) {
  343. /*
  344. * create policy structure, using the default mechanisms but
  345. * with only the security services requested on the command line,
  346. * using the right SSRC value
  347. */
  348. switch (sec_servs) {
  349. case sec_serv_conf_and_auth:
  350. if (gcm_on) {
  351. #ifdef OPENSSL
  352. switch (scs.key_size) {
  353. case 128:
  354. if (scs.tag_size == 16) {
  355. srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
  356. srtp_crypto_policy_set_aes_gcm_128_16_auth(
  357. &policy.rtcp);
  358. } else {
  359. srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
  360. srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
  361. }
  362. break;
  363. case 256:
  364. if (scs.tag_size == 16) {
  365. srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
  366. srtp_crypto_policy_set_aes_gcm_256_16_auth(
  367. &policy.rtcp);
  368. } else {
  369. srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
  370. srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
  371. }
  372. break;
  373. }
  374. #else
  375. fprintf(stderr, "error: GCM mode only supported when using the "
  376. "OpenSSL crypto engine.\n");
  377. return 0;
  378. #endif
  379. } else {
  380. switch (scs.key_size) {
  381. case 128:
  382. if (scs.tag_size == 4) {
  383. srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(
  384. &policy.rtp);
  385. srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
  386. &policy.rtcp);
  387. } else {
  388. srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
  389. &policy.rtp);
  390. srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
  391. &policy.rtcp);
  392. }
  393. break;
  394. case 192:
  395. #ifdef OPENSSL
  396. if (scs.tag_size == 4) {
  397. srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(
  398. &policy.rtp);
  399. srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
  400. &policy.rtcp);
  401. } else {
  402. srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
  403. &policy.rtp);
  404. srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
  405. &policy.rtcp);
  406. }
  407. #else
  408. fprintf(stderr,
  409. "error: AES 192 mode only supported when using the "
  410. "OpenSSL crypto engine.\n");
  411. return 0;
  412. #endif
  413. break;
  414. case 256:
  415. if (scs.tag_size == 4) {
  416. srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(
  417. &policy.rtp);
  418. srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
  419. &policy.rtcp);
  420. } else {
  421. srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
  422. &policy.rtp);
  423. srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
  424. &policy.rtcp);
  425. }
  426. break;
  427. }
  428. }
  429. break;
  430. case sec_serv_conf:
  431. if (gcm_on) {
  432. fprintf(
  433. stderr,
  434. "error: GCM mode must always be used with auth enabled\n");
  435. return -1;
  436. } else {
  437. switch (scs.key_size) {
  438. case 128:
  439. srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
  440. srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
  441. &policy.rtcp);
  442. break;
  443. case 192:
  444. #ifdef OPENSSL
  445. srtp_crypto_policy_set_aes_cm_192_null_auth(&policy.rtp);
  446. srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
  447. &policy.rtcp);
  448. #else
  449. fprintf(stderr,
  450. "error: AES 192 mode only supported when using the "
  451. "OpenSSL crypto engine.\n");
  452. return 0;
  453. #endif
  454. break;
  455. case 256:
  456. srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
  457. srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
  458. &policy.rtcp);
  459. break;
  460. }
  461. }
  462. break;
  463. case sec_serv_auth:
  464. if (gcm_on) {
  465. #ifdef OPENSSL
  466. switch (scs.key_size) {
  467. case 128:
  468. srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
  469. srtp_crypto_policy_set_aes_gcm_128_8_only_auth(
  470. &policy.rtcp);
  471. break;
  472. case 256:
  473. srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
  474. srtp_crypto_policy_set_aes_gcm_256_8_only_auth(
  475. &policy.rtcp);
  476. break;
  477. }
  478. #else
  479. printf("error: GCM mode only supported when using the OpenSSL "
  480. "crypto engine.\n");
  481. return 0;
  482. #endif
  483. } else {
  484. srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
  485. srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
  486. }
  487. break;
  488. default:
  489. fprintf(stderr, "error: unknown security service requested\n");
  490. return -1;
  491. }
  492. policy.key = (uint8_t *)key;
  493. policy.next = NULL;
  494. policy.window_size = 128;
  495. policy.allow_repeat_tx = 0;
  496. policy.rtp.sec_serv = sec_servs;
  497. policy.rtcp.sec_serv =
  498. sec_servs; // sec_serv_none; /* we don't do RTCP anyway */
  499. fprintf(stderr, "setting tag len %d\n", scs.tag_size);
  500. policy.rtp.auth_tag_len = scs.tag_size;
  501. if (gcm_on && scs.tag_size != 8) {
  502. fprintf(stderr, "set tag len %d\n", scs.tag_size);
  503. policy.rtp.auth_tag_len = scs.tag_size;
  504. }
  505. /*
  506. * read key from hexadecimal or base64 on command line into an octet
  507. * string
  508. */
  509. if (b64_input) {
  510. int pad;
  511. expected_len = policy.rtp.cipher_key_len * 4 / 3;
  512. len = base64_string_to_octet_string(key, &pad, input_key,
  513. strlen(input_key));
  514. } else {
  515. expected_len = policy.rtp.cipher_key_len * 2;
  516. len = hex_string_to_octet_string(key, input_key, expected_len);
  517. }
  518. /* check that hex string is the right length */
  519. if (len < expected_len) {
  520. fprintf(stderr, "error: too few digits in key/salt "
  521. "(should be %d digits, found %d)\n",
  522. expected_len, len);
  523. exit(1);
  524. }
  525. if (strlen(input_key) > policy.rtp.cipher_key_len * 2) {
  526. fprintf(stderr, "error: too many digits in key/salt "
  527. "(should be %d hexadecimal digits, found %u)\n",
  528. policy.rtp.cipher_key_len * 2, (unsigned)strlen(input_key));
  529. exit(1);
  530. }
  531. int key_octets = (scs.key_size / 8);
  532. int salt_octets = policy.rtp.cipher_key_len - key_octets;
  533. fprintf(stderr, "set master key/salt to %s/",
  534. octet_string_hex_string(key, key_octets));
  535. fprintf(stderr, "%s\n",
  536. octet_string_hex_string(key + key_octets, salt_octets));
  537. } else {
  538. fprintf(stderr,
  539. "error: neither encryption or authentication were selected\n");
  540. exit(1);
  541. }
  542. pcap_handle = pcap_open_offline(pcap_file, errbuf);
  543. if (!pcap_handle) {
  544. fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
  545. exit(1);
  546. }
  547. assert(pcap_handle != NULL);
  548. if ((pcap_compile(pcap_handle, &fp, filter_exp, 1, pcap_net)) == -1) {
  549. fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp,
  550. pcap_geterr(pcap_handle));
  551. return (2);
  552. }
  553. if (pcap_setfilter(pcap_handle, &fp) == -1) {
  554. fprintf(stderr, "couldn't install filter %s: %s\n", filter_exp,
  555. pcap_geterr(pcap_handle));
  556. return (2);
  557. }
  558. dec = rtp_decoder_alloc();
  559. if (dec == NULL) {
  560. fprintf(stderr, "error: malloc() failed\n");
  561. exit(1);
  562. }
  563. fprintf(stderr, "Starting decoder\n");
  564. if (rtp_decoder_init(dec, policy, mode, rtp_packet_offset)) {
  565. fprintf(stderr, "error: init failed\n");
  566. exit(1);
  567. }
  568. pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
  569. if (dec->mode == mode_rtp || dec->mode == mode_rtcp_mux) {
  570. fprintf(stderr, "RTP packets decoded: %d\n", dec->rtp_cnt);
  571. }
  572. if (dec->mode == mode_rtcp || dec->mode == mode_rtcp_mux) {
  573. fprintf(stderr, "RTCP packets decoded: %d\n", dec->rtcp_cnt);
  574. }
  575. fprintf(stderr, "Packet decode errors: %d\n", dec->error_cnt);
  576. rtp_decoder_deinit(dec);
  577. rtp_decoder_dealloc(dec);
  578. status = srtp_shutdown();
  579. if (status) {
  580. fprintf(stderr, "error: srtp shutdown failed with error code %d\n",
  581. status);
  582. exit(1);
  583. }
  584. return 0;
  585. }
  586. void usage(char *string)
  587. {
  588. fprintf(
  589. stderr,
  590. "usage: %s [-d <debug>]* [[-k][-b] <key>] [-a][-t][-e] [-s "
  591. "<srtp-crypto-suite>] [-m <mode>]\n"
  592. "or %s -l\n"
  593. "where -a use message authentication\n"
  594. " -e <key size> use encryption (use 128 or 256 for key size)\n"
  595. " -g Use AES-GCM mode (must be used with -e)\n"
  596. " -t <tag size> Tag size to use (in GCM mode use 8 or 16)\n"
  597. " -k <key> sets the srtp master key given in hexadecimal\n"
  598. " -b <key> sets the srtp master key given in base64\n"
  599. " -l list debug modules\n"
  600. " -f \"<pcap filter>\" to filter only the desired SRTP packets\n"
  601. " -d <debug> turn on debugging for module <debug>\n"
  602. " -s \"<srtp-crypto-suite>\" to set both key and tag size based\n"
  603. " on RFC4568-style crypto suite specification\n"
  604. " -m <mode> set the mode to be one of [rtp]|rtcp|rtcp-mux\n"
  605. " -p <pcap file> path to pcap file (defaults to stdin)\n"
  606. " -o byte offset of RTP packet in capture (defaults to 42)\n",
  607. string, string);
  608. exit(1);
  609. }
  610. rtp_decoder_t rtp_decoder_alloc(void)
  611. {
  612. return (rtp_decoder_t)malloc(sizeof(rtp_decoder_ctx_t));
  613. }
  614. void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx)
  615. {
  616. free(rtp_ctx);
  617. }
  618. int rtp_decoder_deinit(rtp_decoder_t decoder)
  619. {
  620. if (decoder->srtp_ctx) {
  621. return srtp_dealloc(decoder->srtp_ctx);
  622. }
  623. return 0;
  624. }
  625. int rtp_decoder_init(rtp_decoder_t dcdr,
  626. srtp_policy_t policy,
  627. rtp_decoder_mode_t mode,
  628. int rtp_packet_offset)
  629. {
  630. dcdr->rtp_offset = rtp_packet_offset;
  631. dcdr->srtp_ctx = NULL;
  632. dcdr->start_tv.tv_usec = 0;
  633. dcdr->start_tv.tv_sec = 0;
  634. dcdr->frame_nr = -1;
  635. dcdr->error_cnt = 0;
  636. dcdr->rtp_cnt = 0;
  637. dcdr->rtcp_cnt = 0;
  638. dcdr->mode = mode;
  639. dcdr->policy = policy;
  640. dcdr->policy.ssrc.type = ssrc_any_inbound;
  641. if (srtp_create(&dcdr->srtp_ctx, &dcdr->policy)) {
  642. return 1;
  643. }
  644. return 0;
  645. }
  646. /*
  647. * decodes key as base64
  648. */
  649. void hexdump(const void *ptr, size_t size)
  650. {
  651. int i, j;
  652. const unsigned char *cptr = ptr;
  653. for (i = 0; i < size; i += 16) {
  654. fprintf(stdout, "%04x ", i);
  655. for (j = 0; j < 16 && i + j < size; j++) {
  656. fprintf(stdout, "%02x ", cptr[i + j]);
  657. }
  658. fprintf(stdout, "\n");
  659. }
  660. }
  661. void rtp_decoder_handle_pkt(u_char *arg,
  662. const struct pcap_pkthdr *hdr,
  663. const u_char *bytes)
  664. {
  665. rtp_decoder_t dcdr = (rtp_decoder_t)arg;
  666. rtp_msg_t message;
  667. int rtp;
  668. int pktsize;
  669. struct timeval delta;
  670. int octets_recvd;
  671. srtp_err_status_t status;
  672. dcdr->frame_nr++;
  673. if ((dcdr->start_tv.tv_sec == 0) && (dcdr->start_tv.tv_usec == 0)) {
  674. dcdr->start_tv = hdr->ts;
  675. }
  676. if (hdr->caplen < dcdr->rtp_offset) {
  677. return;
  678. }
  679. const void *rtp_packet = bytes + dcdr->rtp_offset;
  680. memcpy((void *)&message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
  681. pktsize = hdr->caplen - dcdr->rtp_offset;
  682. octets_recvd = pktsize;
  683. if (octets_recvd == -1) {
  684. return;
  685. }
  686. if (dcdr->mode == mode_rtp) {
  687. rtp = 1;
  688. } else if (dcdr->mode == mode_rtcp) {
  689. rtp = 0;
  690. } else {
  691. rtp = 1;
  692. if (octets_recvd >= 2) {
  693. /* rfc5761 */
  694. u_char payload_type = *(bytes + dcdr->rtp_offset + 1) & 0x7f;
  695. rtp = payload_type < 64 || payload_type > 95;
  696. }
  697. }
  698. if (rtp) {
  699. /* verify rtp header */
  700. if (message.header.version != 2) {
  701. return;
  702. }
  703. status = srtp_unprotect(dcdr->srtp_ctx, &message, &octets_recvd);
  704. if (status) {
  705. dcdr->error_cnt++;
  706. return;
  707. }
  708. dcdr->rtp_cnt++;
  709. } else {
  710. status = srtp_unprotect_rtcp(dcdr->srtp_ctx, &message, &octets_recvd);
  711. if (status) {
  712. dcdr->error_cnt++;
  713. return;
  714. }
  715. dcdr->rtcp_cnt++;
  716. }
  717. timersub(&hdr->ts, &dcdr->start_tv, &delta);
  718. fprintf(stdout, "%02ld:%02ld.%06ld\n", delta.tv_sec / 60, delta.tv_sec % 60,
  719. (long)delta.tv_usec);
  720. hexdump(&message, octets_recvd);
  721. }