| OLD | NEW |
| 1 /* | 1 /* |
| 2 * rtpw.c | 2 * rtpw.c |
| 3 * | 3 * |
| 4 * rtp word sender/receiver | 4 * rtp word sender/receiver |
| 5 * | 5 * |
| 6 * David A. McGrew | 6 * David A. McGrew |
| 7 * Cisco Systems, Inc. | 7 * Cisco Systems, Inc. |
| 8 * | 8 * |
| 9 * This app is a simple RTP application intended only for testing | 9 * This app is a simple RTP application intended only for testing |
| 10 * libsrtp. It reads one word at a time from /usr/dict/words (or | 10 * libsrtp. It reads one word at a time from /usr/dict/words (or |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
| 49 * OF THE POSSIBILITY OF SUCH DAMAGE. | 49 * OF THE POSSIBILITY OF SUCH DAMAGE. |
| 50 * | 50 * |
| 51 */ | 51 */ |
| 52 | 52 |
| 53 | 53 |
| 54 #ifdef HAVE_CONFIG_H | 54 #ifdef HAVE_CONFIG_H |
| 55 #include <config.h> | 55 #include <config.h> |
| 56 #endif | 56 #endif |
| 57 | 57 |
| 58 #include "datatypes.h" | |
| 59 #include "getopt_s.h" /* for local getopt() */ | 58 #include "getopt_s.h" /* for local getopt() */ |
| 60 | 59 |
| 61 #include <stdio.h> /* for printf, fprintf */ | 60 #include <stdio.h> /* for printf, fprintf */ |
| 62 #include <stdlib.h> /* for atoi() */ | 61 #include <stdlib.h> /* for atoi() */ |
| 63 #include <errno.h> | 62 #include <errno.h> |
| 64 #include <signal.h> /* for signal() */ | 63 #include <signal.h> /* for signal() */ |
| 65 | 64 |
| 66 #include <string.h> /* for strncpy() */ | 65 #include <string.h> /* for strncpy() */ |
| 67 #include <time.h> /* for usleep() */ | 66 #include <time.h> /* for usleep() */ |
| 68 | 67 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 81 # include <winsock2.h> | 80 # include <winsock2.h> |
| 82 # include <ws2tcpip.h> | 81 # include <ws2tcpip.h> |
| 83 # define RTPW_USE_WINSOCK2 1 | 82 # define RTPW_USE_WINSOCK2 1 |
| 84 #endif | 83 #endif |
| 85 #ifdef HAVE_ARPA_INET_H | 84 #ifdef HAVE_ARPA_INET_H |
| 86 # include <arpa/inet.h> | 85 # include <arpa/inet.h> |
| 87 #endif | 86 #endif |
| 88 | 87 |
| 89 #include "srtp.h" | 88 #include "srtp.h" |
| 90 #include "rtp.h" | 89 #include "rtp.h" |
| 91 #include "crypto_kernel.h" | 90 #include "util.h" |
| 92 | 91 |
| 93 #ifdef RTPW_USE_WINSOCK2 | 92 #ifdef RTPW_USE_WINSOCK2 |
| 94 # define DICT_FILE "words.txt" | 93 # define DICT_FILE "words.txt" |
| 95 #else | 94 #else |
| 96 # define DICT_FILE "/usr/share/dict/words" | 95 # define DICT_FILE "/usr/share/dict/words" |
| 97 #endif | 96 #endif |
| 98 #define USEC_RATE (5e5) | 97 #define USEC_RATE (5e5) |
| 99 #define MAX_WORD_LEN 128 | 98 #define MAX_WORD_LEN 128 |
| 100 #define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a)) | 99 #define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a)) |
| 101 #define MAX_KEY_LEN 96 | 100 #define MAX_KEY_LEN 96 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 FILE *dict; | 149 FILE *dict; |
| 151 char word[MAX_WORD_LEN]; | 150 char word[MAX_WORD_LEN]; |
| 152 int sock, ret; | 151 int sock, ret; |
| 153 struct in_addr rcvr_addr; | 152 struct in_addr rcvr_addr; |
| 154 struct sockaddr_in name; | 153 struct sockaddr_in name; |
| 155 struct ip_mreq mreq; | 154 struct ip_mreq mreq; |
| 156 #if BEW | 155 #if BEW |
| 157 struct sockaddr_in local; | 156 struct sockaddr_in local; |
| 158 #endif | 157 #endif |
| 159 program_type prog_type = unknown; | 158 program_type prog_type = unknown; |
| 160 sec_serv_t sec_servs = sec_serv_none; | 159 srtp_sec_serv_t sec_servs = sec_serv_none; |
| 161 unsigned char ttl = 5; | 160 unsigned char ttl = 5; |
| 162 int c; | 161 int c; |
| 163 int key_size = 128; | 162 int key_size = 128; |
| 164 int tag_size = 8; | 163 int tag_size = 8; |
| 165 int gcm_on = 0; | 164 int gcm_on = 0; |
| 166 char *input_key = NULL; | 165 char *input_key = NULL; |
| 167 int b64_input = 0; | 166 int b64_input = 0; |
| 168 char *address = NULL; | 167 char *address = NULL; |
| 169 char key[MAX_KEY_LEN]; | 168 char key[MAX_KEY_LEN]; |
| 170 unsigned short port = 0; | 169 unsigned short port = 0; |
| 171 rtp_sender_t snd; | 170 rtp_sender_t snd; |
| 172 srtp_policy_t policy; | 171 srtp_policy_t policy; |
| 173 err_status_t status; | 172 srtp_err_status_t status; |
| 174 int len; | 173 int len; |
| 175 int expected_len; | 174 int expected_len; |
| 176 int do_list_mods = 0; | 175 int do_list_mods = 0; |
| 177 uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */ | 176 uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */ |
| 178 #ifdef RTPW_USE_WINSOCK2 | 177 #ifdef RTPW_USE_WINSOCK2 |
| 179 WORD wVersionRequested = MAKEWORD(2, 0); | 178 WORD wVersionRequested = MAKEWORD(2, 0); |
| 180 WSADATA wsaData; | 179 WSADATA wsaData; |
| 181 | 180 |
| 182 ret = WSAStartup(wVersionRequested, &wsaData); | 181 ret = WSAStartup(wVersionRequested, &wsaData); |
| 183 if (ret != 0) { | 182 if (ret != 0) { |
| 184 fprintf(stderr, "error: WSAStartup() failed: %d\n", ret); | 183 fprintf(stderr, "error: WSAStartup() failed: %d\n", ret); |
| 185 exit(1); | 184 exit(1); |
| 186 } | 185 } |
| 187 #endif | 186 #endif |
| 188 | 187 |
| 188 memset(&policy, 0x0, sizeof(srtp_policy_t)); |
| 189 |
| 189 printf("Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version()); | 190 printf("Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version()); |
| 190 | 191 |
| 191 if (setup_signal_handler(argv[0]) != 0) { | 192 if (setup_signal_handler(argv[0]) != 0) { |
| 192 exit(1); | 193 exit(1); |
| 193 } | 194 } |
| 194 | 195 |
| 195 /* initialize srtp library */ | 196 /* initialize srtp library */ |
| 196 status = srtp_init(); | 197 status = srtp_init(); |
| 197 if (status) { | 198 if (status) { |
| 198 printf("error: srtp initialization failed with error code %d\n", status); | 199 printf("error: srtp initialization failed with error code %d\n", status); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 gcm_on = 1; | 235 gcm_on = 1; |
| 235 sec_servs |= sec_serv_auth; | 236 sec_servs |= sec_serv_auth; |
| 236 break; | 237 break; |
| 237 case 'r': | 238 case 'r': |
| 238 prog_type = receiver; | 239 prog_type = receiver; |
| 239 break; | 240 break; |
| 240 case 's': | 241 case 's': |
| 241 prog_type = sender; | 242 prog_type = sender; |
| 242 break; | 243 break; |
| 243 case 'd': | 244 case 'd': |
| 244 status = crypto_kernel_set_debug_module(optarg_s, 1); | 245 status = srtp_set_debug_module(optarg_s, 1); |
| 245 if (status) { | 246 if (status) { |
| 246 printf("error: set debug module (%s) failed\n", optarg_s); | 247 printf("error: set debug module (%s) failed\n", optarg_s); |
| 247 exit(1); | 248 exit(1); |
| 248 } | 249 } |
| 249 break; | 250 break; |
| 250 case 'l': | 251 case 'l': |
| 251 do_list_mods = 1; | 252 do_list_mods = 1; |
| 252 break; | 253 break; |
| 253 default: | 254 default: |
| 254 usage(argv[0]); | 255 usage(argv[0]); |
| 255 } | 256 } |
| 256 } | 257 } |
| 257 | 258 |
| 258 if (prog_type == unknown) { | 259 if (prog_type == unknown) { |
| 259 if (do_list_mods) { | 260 if (do_list_mods) { |
| 260 status = crypto_kernel_list_debug_modules(); | 261 status = srtp_list_debug_modules(); |
| 261 if (status) { | 262 if (status) { |
| 262 printf("error: list of debug modules failed\n"); | 263 printf("error: list of debug modules failed\n"); |
| 263 exit(1); | 264 exit(1); |
| 264 } | 265 } |
| 265 return 0; | 266 return 0; |
| 266 } else { | 267 } else { |
| 267 printf("error: neither sender [-s] nor receiver [-r] specified\n"); | 268 printf("error: neither sender [-s] nor receiver [-r] specified\n"); |
| 268 usage(argv[0]); | 269 usage(argv[0]); |
| 269 } | 270 } |
| 270 } | 271 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 printf("security services: "); | 350 printf("security services: "); |
| 350 if (sec_servs & sec_serv_conf) | 351 if (sec_servs & sec_serv_conf) |
| 351 printf("confidentiality "); | 352 printf("confidentiality "); |
| 352 if (sec_servs & sec_serv_auth) | 353 if (sec_servs & sec_serv_auth) |
| 353 printf("message authentication"); | 354 printf("message authentication"); |
| 354 if (sec_servs == sec_serv_none) | 355 if (sec_servs == sec_serv_none) |
| 355 printf("none"); | 356 printf("none"); |
| 356 printf("\n"); | 357 printf("\n"); |
| 357 | 358 |
| 358 /* set up the srtp policy and master key */ | 359 /* set up the srtp policy and master key */ |
| 359 memset(&policy, 0, sizeof(policy)); | |
| 360 if (sec_servs) { | 360 if (sec_servs) { |
| 361 /* | 361 /* |
| 362 * create policy structure, using the default mechanisms but | 362 * create policy structure, using the default mechanisms but |
| 363 * with only the security services requested on the command line, | 363 * with only the security services requested on the command line, |
| 364 * using the right SSRC value | 364 * using the right SSRC value |
| 365 */ | 365 */ |
| 366 switch (sec_servs) { | 366 switch (sec_servs) { |
| 367 case sec_serv_conf_and_auth: | 367 case sec_serv_conf_and_auth: |
| 368 if (gcm_on) { | 368 if (gcm_on) { |
| 369 #ifdef OPENSSL | 369 #ifdef OPENSSL |
| 370 switch (key_size) { | 370 switch (key_size) { |
| 371 case 128: | 371 case 128: |
| 372 » crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp); | 372 » srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp); |
| 373 » crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp); | 373 » srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp); |
| 374 break; | 374 break; |
| 375 case 256: | 375 case 256: |
| 376 » crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp); | 376 » srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp); |
| 377 » crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp); | 377 » srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp); |
| 378 break; | 378 break; |
| 379 } | 379 } |
| 380 #else | 380 #else |
| 381 printf("error: GCM mode only supported when using the OpenSSL crypto eng
ine.\n"); | 381 printf("error: GCM mode only supported when using the OpenSSL crypto eng
ine.\n"); |
| 382 return 0; | 382 return 0; |
| 383 #endif | 383 #endif |
| 384 } else { | 384 } else { |
| 385 switch (key_size) { | 385 switch (key_size) { |
| 386 case 128: | 386 case 128: |
| 387 crypto_policy_set_rtp_default(&policy.rtp); | 387 srtp_crypto_policy_set_rtp_default(&policy.rtp); |
| 388 crypto_policy_set_rtcp_default(&policy.rtcp); | 388 srtp_crypto_policy_set_rtcp_default(&policy.rtcp); |
| 389 break; | 389 break; |
| 390 case 256: | 390 case 256: |
| 391 crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp); | 391 srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp); |
| 392 crypto_policy_set_rtcp_default(&policy.rtcp); | 392 srtp_crypto_policy_set_rtcp_default(&policy.rtcp); |
| 393 break; | 393 break; |
| 394 } | 394 } |
| 395 } | 395 } |
| 396 break; | 396 break; |
| 397 case sec_serv_conf: | 397 case sec_serv_conf: |
| 398 if (gcm_on) { | 398 if (gcm_on) { |
| 399 printf("error: GCM mode must always be used with auth enabled\n"); | 399 printf("error: GCM mode must always be used with auth enabled\n"); |
| 400 return -1; | 400 return -1; |
| 401 } else { | 401 } else { |
| 402 switch (key_size) { | 402 switch (key_size) { |
| 403 case 128: | 403 case 128: |
| 404 crypto_policy_set_aes_cm_128_null_auth(&policy.rtp); | 404 srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp); |
| 405 crypto_policy_set_rtcp_default(&policy.rtcp); | 405 srtp_crypto_policy_set_rtcp_default(&policy.rtcp); |
| 406 break; | 406 break; |
| 407 case 256: | 407 case 256: |
| 408 crypto_policy_set_aes_cm_256_null_auth(&policy.rtp); | 408 srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp); |
| 409 crypto_policy_set_rtcp_default(&policy.rtcp); | 409 srtp_crypto_policy_set_rtcp_default(&policy.rtcp); |
| 410 break; | 410 break; |
| 411 } | 411 } |
| 412 } | 412 } |
| 413 break; | 413 break; |
| 414 case sec_serv_auth: | 414 case sec_serv_auth: |
| 415 if (gcm_on) { | 415 if (gcm_on) { |
| 416 #ifdef OPENSSL | 416 #ifdef OPENSSL |
| 417 switch (key_size) { | 417 switch (key_size) { |
| 418 case 128: | 418 case 128: |
| 419 » crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp); | 419 » srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp); |
| 420 » crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp); | 420 » srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp); |
| 421 break; | 421 break; |
| 422 case 256: | 422 case 256: |
| 423 » crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp); | 423 » srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp); |
| 424 » crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtcp); | 424 » srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtcp); |
| 425 break; | 425 break; |
| 426 } | 426 } |
| 427 #else | 427 #else |
| 428 printf("error: GCM mode only supported when using the OpenSSL crypto eng
ine.\n"); | 428 printf("error: GCM mode only supported when using the OpenSSL crypto eng
ine.\n"); |
| 429 return 0; | 429 return 0; |
| 430 #endif | 430 #endif |
| 431 } else { | 431 } else { |
| 432 crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp); | 432 srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp); |
| 433 crypto_policy_set_rtcp_default(&policy.rtcp); | 433 srtp_crypto_policy_set_rtcp_default(&policy.rtcp); |
| 434 } | 434 } |
| 435 break; | 435 break; |
| 436 default: | 436 default: |
| 437 printf("error: unknown security service requested\n"); | 437 printf("error: unknown security service requested\n"); |
| 438 return -1; | 438 return -1; |
| 439 } | 439 } |
| 440 policy.ssrc.type = ssrc_specific; | 440 policy.ssrc.type = ssrc_specific; |
| 441 policy.ssrc.value = ssrc; | 441 policy.ssrc.value = ssrc; |
| 442 policy.key = (uint8_t *) key; | 442 policy.key = (uint8_t *) key; |
| 443 policy.ekt = NULL; | 443 policy.ekt = NULL; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 } else { | 488 } else { |
| 489 /* | 489 /* |
| 490 * we're not providing security services, so set the policy to the | 490 * we're not providing security services, so set the policy to the |
| 491 * null policy | 491 * null policy |
| 492 * | 492 * |
| 493 * Note that this policy does not conform to the SRTP | 493 * Note that this policy does not conform to the SRTP |
| 494 * specification, since RTCP authentication is required. However, | 494 * specification, since RTCP authentication is required. However, |
| 495 * the effect of this policy is to turn off SRTP, so that this | 495 * the effect of this policy is to turn off SRTP, so that this |
| 496 * application is now a vanilla-flavored RTP application. | 496 * application is now a vanilla-flavored RTP application. |
| 497 */ | 497 */ |
| 498 srtp_crypto_policy_set_null_cipher_hmac_null(&policy.rtp); |
| 499 srtp_crypto_policy_set_null_cipher_hmac_null(&policy.rtcp); |
| 498 policy.key = (uint8_t *)key; | 500 policy.key = (uint8_t *)key; |
| 499 policy.ssrc.type = ssrc_specific; | 501 policy.ssrc.type = ssrc_specific; |
| 500 policy.ssrc.value = ssrc; | 502 policy.ssrc.value = ssrc; |
| 501 policy.rtp.cipher_type = NULL_CIPHER; | |
| 502 policy.rtp.cipher_key_len = 0; | |
| 503 policy.rtp.auth_type = NULL_AUTH; | |
| 504 policy.rtp.auth_key_len = 0; | |
| 505 policy.rtp.auth_tag_len = 0; | |
| 506 policy.rtp.sec_serv = sec_serv_none; | |
| 507 policy.rtcp.cipher_type = NULL_CIPHER; | |
| 508 policy.rtcp.cipher_key_len = 0; | |
| 509 policy.rtcp.auth_type = NULL_AUTH; | |
| 510 policy.rtcp.auth_key_len = 0; | |
| 511 policy.rtcp.auth_tag_len = 0; | |
| 512 policy.rtcp.sec_serv = sec_serv_none; | |
| 513 policy.window_size = 0; | 503 policy.window_size = 0; |
| 514 policy.allow_repeat_tx = 0; | 504 policy.allow_repeat_tx = 0; |
| 515 policy.ekt = NULL; | 505 policy.ekt = NULL; |
| 516 policy.next = NULL; | 506 policy.next = NULL; |
| 517 } | 507 } |
| 518 | 508 |
| 519 if (prog_type == sender) { | 509 if (prog_type == sender) { |
| 520 | 510 |
| 521 #if BEW | 511 #if BEW |
| 522 /* bind to local socket (to match crypto policy, if need be) */ | 512 /* bind to local socket (to match crypto policy, if need be) */ |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 } | 694 } |
| 705 #else | 695 #else |
| 706 if (signal(SIGTERM, handle_signal) == SIG_ERR) { | 696 if (signal(SIGTERM, handle_signal) == SIG_ERR) { |
| 707 fprintf(stderr, "%s: error setting up signal handler", name); | 697 fprintf(stderr, "%s: error setting up signal handler", name); |
| 708 perror(""); | 698 perror(""); |
| 709 return -1; | 699 return -1; |
| 710 } | 700 } |
| 711 #endif | 701 #endif |
| 712 return 0; | 702 return 0; |
| 713 } | 703 } |
| OLD | NEW |