PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(void) { if (libsrtp_initialized == PJ_FALSE) { err_status_t err; err = srtp_init(); if (err != err_status_ok) { PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s", get_libsrtp_errstr(err))); return PJMEDIA_ERRNO_FROM_LIBSRTP(err); } if (pj_atexit(pjmedia_srtp_deinit_lib) != PJ_SUCCESS) { /* There will be memory leak when it fails to schedule libsrtp * deinitialization, however the memory leak could be harmless, * since in modern OS's memory used by an application is released * when the application terminates. */ PJ_LOG(4, (THIS_FILE, "Failed to register libsrtp deinit.")); } libsrtp_initialized = PJ_TRUE; } return PJ_SUCCESS; }
void CPlayerMedia::rtp_init (bool do_tcp) { rtp_stream_params_t rsp; connect_desc_t *cptr; double bw; if (m_rtp_session == NULL) { m_rtp_session_from_outside = false; rtp_default_params(&rsp); if (find_rtcp_bandwidth_from_media(m_media_info, &bw) < 0) { bw = 5000.0; } rsp.rtcp_bandwidth = bw; cptr = get_connect_desc_from_media(m_media_info); rsp.rtp_addr = m_source_addr == NULL ? cptr->conn_addr : m_source_addr; rsp.rtp_rx_port = m_our_port; rsp.rtp_tx_port = m_server_port; rsp.rtp_ttl = cptr == NULL ? 1 : cptr->ttl; rsp.rtp_callback = c_recv_callback; if (do_tcp) { rsp.dont_init_sockets = 1; rsp.rtcp_send_packet = c_rtcp_send_packet; } else { // udp. See if we have a seperate rtcp field if (m_media_info->rtcp_connect.used) { rsp.rtcp_rx_port = m_media_info->rtcp_port; rsp.rtcp_addr = m_media_info->rtcp_connect.conn_addr; rsp.rtcp_ttl = m_media_info->rtcp_connect.ttl; } if (config.get_config_string(CONFIG_MULTICAST_RX_IF) != NULL) { struct in_addr if_addr; if (getIpAddressFromInterface(config.get_config_string(CONFIG_MULTICAST_RX_IF), &if_addr) >= 0) { rsp.physical_interface_addr = inet_ntoa(if_addr); } } } rsp.recv_userdata = this; m_rtp_session = rtp_init_stream(&rsp); rtp_set_option(m_rtp_session, RTP_OPT_WEAK_VALIDATION, FALSE); rtp_set_option(m_rtp_session, RTP_OPT_PROMISC, TRUE); if (strncasecmp(m_media_info->proto, "RTP/SVP", strlen("RTP/SVP")) == 0) { srtp_init(); } } else { m_rtp_session_from_outside = true; rtp_set_rtp_callback(m_rtp_session, c_recv_callback, this); } m_rtp_inited = 1; }
int main(int argc, char *argv[]) { unsigned do_list_mods = 0; char q; 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 = 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 = 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"); return 0; }
int evrb_crypto_init() { #ifdef USE_SRTP int i=0; if(i=srtp_init()) { fprintf(stderr,"srtp_init() return %i\n",i); return -1; } #endif dh_init(); return 0; }
SrtpChannel::SrtpChannel() { boost::mutex::scoped_lock lock(SrtpChannel::sessionMutex_); if (SrtpChannel::initialized != true) { int res = srtp_init(); ELOG_DEBUG("Initialized SRTP library %d", res); SrtpChannel::initialized = true; } active_ = false; send_session_ = NULL; receive_session_ = NULL; }
srtpw_err_status_t srtpw_srtp_init() { if (g_init_done) { return -1; } if (srtp_init() != err_status_ok) { return -1; } srtp_install_event_handler(srtpw_srtp_event_cb); srtpw_log(err_level_info, "srtpw_srtp_init from srtp_wrapper"); g_init_done =1; return err_status_ok; }
err_status_t ortp_srtp_init(void) { err_status_t st=0; ortp_message("srtp init"); if (!srtp_init_done) { st=srtp_init(); if (st==0) { srtp_init_done++; }else{ ortp_fatal("Couldn't initialize SRTP library."); err_reporting_init("oRTP"); } }else srtp_init_done++; return st; }
JNIEXPORT jint JNICALL Java_org_theonionphone_protocol_SrtpProtocol_initSender (JNIEnv *env, jobject obj, jbyteArray keyByteArray, jbyteArray saltByteArray, jint codecType, jint sampleCount, jint payloadSizeInBytes, jint rtpPacketSizeInBytes, jint srtpPacketSizeInBytes) { srtp_policy_t policy; char key[SRTP_KEY_SIZE]; payloadSize = payloadSizeInBytes; rtpPacketSize = rtpPacketSizeInBytes; srtpPacketSize = srtpPacketSizeInBytes; // copy key and salt to an array needed by srtp (*env)->GetByteArrayRegion(env, keyByteArray, 0, KEY_SIZE, key); (*env)->GetByteArrayRegion(env, saltByteArray, 0, SALT_SIZE, key + KEY_SIZE); //initialize rtp err_status_t status = initRtp(&rtpContext, codecType, sampleCount); if(status) { return status; } //initialize srtp status = srtp_init(); if(status) { return status; } //set up crypto policies crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); crypto_policy_set_rtcp_default(&policy.rtcp); policy.ssrc.type = ssrc_specific; policy.ssrc.value = rtpContext->mSsrc; policy.key = (uint8_t *) key; policy.next = NULL; policy.rtp.sec_serv = sec_serv_conf_and_auth; policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */ //create an srtp stream srtpContextSend = malloc(sizeof(srtp_t*)); if(srtpContextSend == NULL) { return 69; } status = srtp_create(srtpContextSend, &policy); return status; }
static int mod_srtp_init(void) { err_status_t err; err = srtp_init(); if (err_status_ok != err) { DEBUG_WARNING("srtp_init() failed (%H)\n", errstatus_print, err); return ENOSYS; } menc_register(&menc_srtp_opt); menc_register(&menc_srtp_mand); menc_register(&menc_srtp_mandf); return 0; }
static pj_status_t pjmedia_srtp_init_lib(void) { static pj_bool_t initialized = PJ_FALSE; if (initialized == PJ_FALSE) { err_status_t err; err = srtp_init(); if (err != err_status_ok) { PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s", get_libsrtp_errstr(err))); return PJMEDIA_ERRNO_FROM_LIBSRTP(err); } initialized = PJ_TRUE; } return PJ_SUCCESS; }
int krx_init_srtp(krx_srtp* s) { printf("Setting up srtp.\n"); /* initialize */ err_status_t err = err_status_ok; err = srtp_init(); if(err != err_status_ok) { printf("error, code: %d\n", err); return -1; } // see http://mxr.mozilla.org/mozilla-central/source/media/webrtc/signaling/src/mediapipeline/SrtpFlow.cpp //crypto_policy_set_rtp_default(&s->policy.rtp); //crypto_policy_set_rtcp_default(&s->policy.rtcp); crypto_policy_set_aes_cm_128_hmac_sha1_80(&s->policy.rtp); // see SSL_get_selected_srtp_profile() to extract the name crypto_policy_set_aes_cm_128_hmac_sha1_80(&s->policy.rtcp); s->policy.ssrc.type = ssrc_any_inbound; s->policy.key = calloc(1, KRX_SRTP_MASTER_LEN); // @todo(roxlu): make sure to free somewhere s->policy.window_size = 1024; // see: http://mxr.mozilla.org/mozilla-central/source/media/webrtc/signaling/src/mediapipeline/SrtpFlow.cpp s->policy.allow_repeat_tx = 1; // see: http://mxr.mozilla.org/mozilla-central/source/media/webrtc/signaling/src/mediapipeline/SrtpFlow.cpp s->policy.window_size = 128; // see: http://mxr.mozilla.org/mozilla-central/source/media/webrtc/signaling/src/mediapipeline/SrtpFlow.cpp s->policy.allow_repeat_tx = 0; // see: http://mxr.mozilla.org/mozilla-central/source/media/webrtc/signaling/src/mediapipeline/SrtpFlow.cpp s->policy.next = NULL; /* policy.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound; 77 policy.ssrc.value = 0; 78 policy.ekt = nullptr; 79 policy.window_size = 1024; // Use the Chrome value. Needs to be revisited. Default is 128 80 policy.allow_repeat_tx = 1; // Use Chrome value; needed for NACK mode to work 81 policy.next = nullptr; */ if(s->policy.key == NULL) { printf("Error: cannot allocate the policy key.\n"); return -1; } return 0; }
nsresult SrtpFlow::Init() { if (!initialized) { srtp_err_status_t r = srtp_init(); if (r != srtp_err_status_ok) { CSFLogError(LOGTAG, "Could not initialize SRTP"); MOZ_ASSERT(PR_FALSE); return NS_ERROR_FAILURE; } r = srtp_install_event_handler(&SrtpFlow::srtp_event_handler); if (r != srtp_err_status_ok) { CSFLogError(LOGTAG, "Could not install SRTP event handler"); MOZ_ASSERT(PR_FALSE); return NS_ERROR_FAILURE; } initialized = true; } return NS_OK; }
PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt) { pj_status_t status = PJ_SUCCESS; if (libsrtp_initialized) return PJ_SUCCESS; #if PJMEDIA_LIBSRTP_AUTO_INIT_DEINIT /* Init libsrtp */ { srtp_err_status_t err; err = srtp_init(); if (err != srtp_err_status_ok) { PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s", get_libsrtp_errstr(err))); return PJMEDIA_ERRNO_FROM_LIBSRTP(err); } } #endif #if defined(PJMEDIA_SRTP_HAS_DTLS) && (PJMEDIA_SRTP_HAS_DTLS != 0) dtls_init(); #endif if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS) { /* There will be memory leak when it fails to schedule libsrtp * deinitialization, however the memory leak could be harmless, * since in modern OS's memory used by an application is released * when the application terminates. */ PJ_LOG(4, (THIS_FILE, "Failed to register libsrtp deinit.")); } libsrtp_initialized = PJ_TRUE; return status; }
int main (int argc, char *argv[]) { char q; unsigned do_timing_test = 0; unsigned do_rejection_test = 0; unsigned do_codec_timing = 0; unsigned do_validation = 0; unsigned do_list_mods = 0; err_status_t status; /* * verify that the compiler has interpreted the header data * structure srtp_hdr_t correctly */ if (sizeof(srtp_hdr_t) != 12) { printf("error: srtp_hdr_t has incorrect size\n"); exit(1); } /* initialize srtp library */ status = srtp_init(); if (status) { printf("error: srtp init failed with error code %d\n", status); exit(1); } /* load srtp_driver debug module */ status = crypto_kernel_load_debug_module(&mod_driver); if (status) { printf("error: load of srtp_driver debug module failed " "with error code %d\n", status); exit(1); } /* process input arguments */ while (1) { q = getopt(argc, argv, "trcvld:"); if (q == -1) break; switch (q) { case 't': do_timing_test = 1; break; case 'r': do_rejection_test = 1; break; case 'c': do_codec_timing = 1; break; case 'v': do_validation = 1; break; case 'l': do_list_mods = 1; break; case 'd': status = crypto_kernel_set_debug_module(optarg, 1); if (status) { printf("error: set debug module (%s) failed\n", optarg); exit(1); } break; default: usage(argv[0]); } } if (!do_validation && !do_timing_test && !do_codec_timing && !do_list_mods && !do_rejection_test) usage(argv[0]); if (do_list_mods) { status = crypto_kernel_list_debug_modules(); if (status) { printf("error: list of debug modules failed\n"); exit(1); } } if (do_validation) { const srtp_policy_t **policy = policy_array; srtp_policy_t *big_policy; /* loop over policy array, testing srtp and srtcp for each policy */ while (*policy != NULL) { printf("testing srtp_protect and srtp_unprotect\n"); if (srtp_test(*policy) == err_status_ok) printf("passed\n\n"); else { printf("failed\n"); exit(1); } printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n"); if (srtcp_test(*policy) == err_status_ok) printf("passed\n\n"); else { printf("failed\n"); exit(1); } policy++; } /* create a big policy list and run tests on it */ status = srtp_create_big_policy(&big_policy); if (status) { printf("unexpected failure with error code %d\n", status); exit(1); } printf("testing srtp_protect and srtp_unprotect with big policy\n"); if (srtp_test(big_policy) == err_status_ok) printf("passed\n\n"); else { printf("failed\n"); exit(1); } /* run test on wildcard policy */ printf("testing srtp_protect and srtp_unprotect on " "wildcard ssrc policy\n"); if (srtp_test(&wildcard_policy) == err_status_ok) printf("passed\n\n"); else { printf("failed\n"); exit(1); } /* * run validation test against the reference packets - note * that this test only covers the default policy */ printf("testing srtp_protect and srtp_unprotect against " "reference packets\n"); if (srtp_validate() == err_status_ok) printf("passed\n\n"); else { printf("failed\n"); exit(1); } /* * test the function srtp_remove_stream() */ printf("testing srtp_remove_stream()..."); if (srtp_test_remove_stream() == err_status_ok) printf("passed\n"); else { printf("failed\n"); exit(1); } } if (do_timing_test) { const srtp_policy_t **policy = policy_array; /* loop over policies, run timing test for each */ while (*policy != NULL) { srtp_print_policy(*policy); srtp_do_timing(*policy); policy++; } } if (do_rejection_test) { const srtp_policy_t **policy = policy_array; /* loop over policies, run rejection timing test for each */ while (*policy != NULL) { srtp_print_policy(*policy); srtp_do_rejection_timing(*policy); policy++; } } if (do_codec_timing) { srtp_policy_t policy; int ignore; double mips = mips_estimate(1000000000, &ignore); crypto_policy_set_rtp_default(&policy.rtp); crypto_policy_set_rtcp_default(&policy.rtcp); policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xdecafbad; policy.key = test_key; policy.next = NULL; printf("mips estimate: %e\n", mips); printf("testing srtp processing time for voice codecs:\n"); printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n"); printf("G.711\t\t%d\t\t\t%e\n", 80, (double) mips * (80 * 8) / srtp_bits_per_second(80, &policy) / .01 ); printf("G.711\t\t%d\t\t\t%e\n", 160, (double) mips * (160 * 8) / srtp_bits_per_second(160, &policy) / .02); printf("G.726-32\t%d\t\t\t%e\n", 40, (double) mips * (40 * 8) / srtp_bits_per_second(40, &policy) / .01 ); printf("G.726-32\t%d\t\t\t%e\n", 80, (double) mips * (80 * 8) / srtp_bits_per_second(80, &policy) / .02); printf("G.729\t\t%d\t\t\t%e\n", 10, (double) mips * (10 * 8) / srtp_bits_per_second(10, &policy) / .01 ); printf("G.729\t\t%d\t\t\t%e\n", 20, (double) mips * (20 * 8) / srtp_bits_per_second(20, &policy) / .02 ); } return 0; }
int main(int, char **) { err_status_t status = srtp_init(); return status == err_status_ok; }
/* DTLS-SRTP initialization */ gint janus_dtls_srtp_init(const char* server_pem, const char* server_key) { /* FIXME First of all make OpenSSL thread safe (see note above on issue #316) */ janus_dtls_locks = g_malloc0(sizeof(*janus_dtls_locks) * CRYPTO_num_locks()); int l=0; for(l = 0; l < CRYPTO_num_locks(); l++) { janus_mutex_init(&janus_dtls_locks[l]); } CRYPTO_THREADID_set_callback(janus_dtls_cb_openssl_threadid); CRYPTO_set_locking_callback(janus_dtls_cb_openssl_lock); /* Go on and create the DTLS context */ ssl_ctx = SSL_CTX_new(DTLSv1_method()); if(!ssl_ctx) { JANUS_LOG(LOG_FATAL, "Ops, error creating DTLS context?\n"); return -1; } SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, janus_dtls_verify_callback); SSL_CTX_set_tlsext_use_srtp(ssl_ctx, "SRTP_AES128_CM_SHA1_80"); /* FIXME Should we support something else as well? */ if (!server_pem && !server_key) { JANUS_LOG(LOG_WARN, "No cert/key specified, autogenerating some...\n"); if (janus_dtls_generate_keys(&ssl_cert, &ssl_key) != 0) { JANUS_LOG(LOG_FATAL, "Error generating DTLS key/certificate\n"); return -2; } } else if (!server_pem || !server_key) { JANUS_LOG(LOG_FATAL, "DTLS certificate and key must be specified\n"); return -2; } else if (janus_dtls_load_keys(server_pem, server_key, &ssl_cert, &ssl_key) != 0) { return -3; } if(!SSL_CTX_use_certificate(ssl_ctx, ssl_cert)) { JANUS_LOG(LOG_FATAL, "Certificate error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -4; } if(!SSL_CTX_use_PrivateKey(ssl_ctx, ssl_key)) { JANUS_LOG(LOG_FATAL, "Certificate key error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -5; } if(!SSL_CTX_check_private_key(ssl_ctx)) { JANUS_LOG(LOG_FATAL, "Certificate check error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -6; } SSL_CTX_set_read_ahead(ssl_ctx,1); unsigned int size; unsigned char fingerprint[EVP_MAX_MD_SIZE]; if(X509_digest(ssl_cert, EVP_sha256(), (unsigned char *)fingerprint, &size) == 0) { JANUS_LOG(LOG_FATAL, "Error converting X509 structure (%s)\n", ERR_reason_error_string(ERR_get_error())); return -7; } char *lfp = (char *)&local_fingerprint; unsigned int i = 0; for(i = 0; i < size; i++) { g_snprintf(lfp, 4, "%.2X:", fingerprint[i]); lfp += 3; } *(lfp-1) = 0; JANUS_LOG(LOG_INFO, "Fingerprint of our certificate: %s\n", local_fingerprint); SSL_CTX_set_cipher_list(ssl_ctx, DTLS_CIPHERS); /* Initialize libsrtp */ if(srtp_init() != err_status_ok) { JANUS_LOG(LOG_FATAL, "Ops, error setting up libsrtp?\n"); return 5; } return 0; }
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; int key_size = 128; int tag_size = 8; 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] = ""; rtp_decoder_t dec; srtp_policy_t policy; 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); } /* check args */ while (1) { c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:"); 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) { fprintf(stderr, "error: encryption key size must be 128 or 256 (%d)\n", key_size); exit(1); } input_key = malloc(key_size); sec_servs |= sec_serv_conf; break; case 't': tag_size = atoi(optarg_s); if (tag_size != 8 && tag_size != 16) { fprintf(stderr, "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 'd': status = srtp_crypto_kernel_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; default: usage(argv[0]); } } if (do_list_mods) { status = srtp_crypto_kernel_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 (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 fprintf(stderr, "error: GCM mode only supported when using the OpenSSL 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) { fprintf(stderr, "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 OPENSSL 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: 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", tag_size); policy.rtp.auth_tag_len = tag_size; if (gcm_on && tag_size != 8) { fprintf(stderr, "setted tag len %d\n", tag_size); 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 (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); } fprintf(stderr, "set master key/salt to %s/", octet_string_hex_string(key, 16)); fprintf(stderr, "%s\n", octet_string_hex_string(key+16, 14)); } else { fprintf(stderr, "error: neither encryption or authentication were selected"); exit(1); } pcap_handle = pcap_open_offline("-", 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"); rtp_decoder_init(dec, policy); pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec); rtp_decoder_deinit_srtp(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; }
/* DTLS-SRTP initialization */ gint janus_dtls_srtp_init(gchar *server_pem, gchar *server_key) { ssl_ctx = SSL_CTX_new(DTLSv1_method()); if(!ssl_ctx) { JANUS_LOG(LOG_FATAL, "Ops, error creating DTLS context?\n"); return -1; } SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, janus_dtls_verify_callback); SSL_CTX_set_tlsext_use_srtp(ssl_ctx, "SRTP_AES128_CM_SHA1_80"); /* FIXME Should we support something else as well? */ if(!server_pem || !SSL_CTX_use_certificate_file(ssl_ctx, server_pem, SSL_FILETYPE_PEM)) { JANUS_LOG(LOG_FATAL, "Certificate error, does it exist?\n"); JANUS_LOG(LOG_FATAL, " %s\n", server_pem); return -2; } if(!server_key || !SSL_CTX_use_PrivateKey_file(ssl_ctx, server_key, SSL_FILETYPE_PEM)) { JANUS_LOG(LOG_FATAL, "Certificate key error, does it exist?\n"); JANUS_LOG(LOG_FATAL, " %s\n", server_key); return -3; } if(!SSL_CTX_check_private_key(ssl_ctx)) { JANUS_LOG(LOG_FATAL, "Certificate check error...\n"); return -4; } SSL_CTX_set_read_ahead(ssl_ctx,1); BIO *certbio = BIO_new(BIO_s_file()); if(certbio == NULL) { JANUS_LOG(LOG_FATAL, "Certificate BIO error...\n"); return -5; } if(BIO_read_filename(certbio, server_pem) == 0) { JANUS_LOG(LOG_FATAL, "Error reading certificate...\n"); BIO_free_all(certbio); return -6; } X509 *cert = PEM_read_bio_X509(certbio, NULL, 0, NULL); if(cert == NULL) { JANUS_LOG(LOG_FATAL, "Error reading certificate...\n"); BIO_free_all(certbio); return -7; } unsigned int size; unsigned char fingerprint[EVP_MAX_MD_SIZE]; if(X509_digest(cert, EVP_sha256(), (unsigned char *)fingerprint, &size) == 0) { JANUS_LOG(LOG_FATAL, "Error converting X509 structure...\n"); X509_free(cert); BIO_free_all(certbio); return -7; } char *lfp = (char *)&local_fingerprint; unsigned int i = 0; for(i = 0; i < size; i++) { g_snprintf(lfp, 4, "%.2X:", fingerprint[i]); lfp += 3; } *(lfp-1) = 0; JANUS_LOG(LOG_INFO, "Fingerprint of our certificate: %s\n", local_fingerprint); X509_free(cert); BIO_free_all(certbio); SSL_CTX_set_cipher_list(ssl_ctx, DTLS_CIPHERS); /* Initialize libsrtp */ if(srtp_init() != err_status_ok) { JANUS_LOG(LOG_FATAL, "Ops, error setting up libsrtp?\n"); return 5; } return 0; }
int main (int argc, char *argv[]) { struct rtp *session; int rx_port, tx_port, fd; uint32_t read_size, packet_size, number_of_packet; uint8_t buff[BUFFSIZE]; off_t cur_pos; char *ip_addr; char filename[1024]; int c; struct hostent *h; struct utsname myname; #ifdef HAVE_SRTP #else void *srtp_data; #endif unsigned int extra_len; int do_auth = 1, do_encrypt = 1; ssize_t readit; ssize_t sendit; int do_rtcp = false; // Setting of default session if(uname(&myname) < 0){ fprintf(stderr,"uname\n"); exit(1); } if((h = gethostbyname(myname.nodename)) == NULL) { herror("gethostbyname"); exit(1); } ip_addr = strdup(inet_ntoa(*((struct in_addr *)h->h_addr))); rx_port = 15002; tx_port = 15000; // Option opterr = 0; while((c = getopt(argc, argv, "acdehi:r:t:f:")) != -1){ switch (c) { case 'a': do_auth = 0; break; case 'c': do_rtcp = 1; break; case 'd': dump_pak = true; break; case 'e': do_encrypt = 0; break; case 'h': printf("Usage: ./test_rtp_client -i <IP_Addr> -r <rx_port> -t <tx_port> -f <filename>\n"); printf("Default values are as follows...\n"); printf("ip_addr = %s\n", ip_addr); printf("rx_port = %d\n", rx_port); printf("tx_port = %d\n", tx_port); printf("Filename = %s\n", filename); exit(-1); case 'i': strcpy(ip_addr, optarg); break; case 'r': rx_port = atoi(optarg); break; case 't': tx_port = atoi(optarg); break; case 'f': strcpy(filename,optarg); break; case '?': printf("usage: ./test_rtp_client -i <IP_Addr> -r <rx_port> -t <tx_port> -f <filename>\n"); exit(1); } } if (optind < argc) { for(; optind < argc; optind++) { printf("error->%s(#%d): put -[i|r|t|f] \n", argv[optind],optind-1); } exit(1); } // display session information printf("\n-Session Information-\n"); printf(" ip_addr = %s\n", ip_addr); printf(" rx_port = %d\n", rx_port); printf(" tx_port = %d\n", tx_port); printf(" filename = %s\n", filename); printf("Press Return key..."); // getchar(); // Open Original File to compare with received file if((fd = open(filename, O_RDONLY)) == -1){ perror(filename); exit(1); } rtp_stream_params_t rsp; rtp_default_params(&rsp); rsp.rtp_addr = ip_addr; rsp.rtp_rx_port = rx_port; rsp.rtp_tx_port = tx_port; rsp.rtp_ttl = TTL; rsp.rtcp_bandwidth = RTCP_BW; rsp.rtp_callback = c_rtp_callback; rsp.transmit_initial_rtcp = 1; if ( (session = rtp_init_stream(&rsp) ) == NULL){ exit(-1); } rtp_set_my_ssrc(session,OUR_SSRC); #ifdef HAVE_SRTP /////////// start will //set NULL security services //uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */ srtp_policy_t policy; char key[64]; char keystr[128]; uint ix; #if 1 strcpy(keystr, "c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451"); hex_string_to_octet_string(key, keystr, 60); #else memset(key, 0, sizeof(key)); #endif for (ix = 0; ix < 30; ix++) { printf("%02x ", key[ix]); } printf("\n"); #if 0 // NULL cipher policy.key = (uint8_t *) key; policy.ssrc.type = ssrc_any_outbound; //ssrc_specific; policy.ssrc.value = 0x96;//OUR_SSRC; policy.rtp.cipher_type = NULL_CIPHER; policy.rtp.cipher_key_len = 0; policy.rtp.auth_type = NULL_AUTH; policy.rtp.auth_key_len = 0; policy.rtp.auth_tag_len = 0; policy.rtp.sec_serv = sec_serv_none; policy.rtcp.cipher_type = NULL_CIPHER; policy.rtcp.cipher_key_len = 0; policy.rtcp.auth_type = NULL_AUTH; policy.rtcp.auth_key_len = 0; policy.rtcp.auth_tag_len = 0; policy.rtcp.sec_serv = sec_serv_none; policy.next = NULL; #else //confidentiality only, no auth crypto_policy_set_aes_cm_128_null_auth(&policy.rtp); crypto_policy_set_rtcp_default(&policy.rtcp); policy.ssrc.type = ssrc_any_outbound; policy.key = (uint8_t *) key; policy.next = NULL; policy.rtp.sec_serv = sec_serv_conf;//sec_servs; policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */ #endif err_status_t status; printf("ABOUT TO SRTP_INIT\n"); status = srtp_init(); if (status) { printf("error: srtp initialization failed with error code %d\n", status); exit(1); } printf("ABOUT TO SRTP_CREAT\n"); srtp_ctx_t *srtp_ctx = NULL; status = srtp_create(&srtp_ctx, &policy); if (status) { printf("error: srtp_create() failed with code %d\n", status); exit(1); } printf("DONE WITH SRTP_CREATE\n"); extra_len = 0; #else extra_len = 0; srtp_data = NULL; #endif rtp_encryption_params_t params; params.rtp_encrypt = ENCRYPT_FUNCTION; params.rtcp_encrypt = RTCP_ENCRYPT_FUNCTION; params.rtp_decrypt = DECRYPT_FUNCTION; params.rtcp_decrypt = RTCP_DECRYPT_FUNCTION; params.userdata = srtp_data; params.rtp_auth_alloc_extra = params.rtcp_auth_alloc_extra = 0; rtp_set_encryption_params(session, ¶ms); if (do_rtcp) { rtcp_file = fopen("server.rtcp", FOPEN_WRITE_BINARY); } cur_pos = 0; packet_size = 64; number_of_packet = 0; while(1) { // change BUFFSIZE to be an incrementing value from 64 to 1450 if(packet_size > 1450) packet_size = 725; readit = read(fd, buff, packet_size); if (readit < 0) { perror("file read"); exit(1); } read_size = readit; //int buflen = readit; if (read_size == 0) break; //printf("about to protect\n"); #if 0 sendit = rtp_send_data(session, cur_pos, 97,//pt 0,//m 0,//cc NULL, //csrc[], buff,//data read_size,//data_len NULL,//*extn 0, 0); #else { struct iovec iov[2]; iov[0].iov_len = read_size % 48; if (iov[0].iov_len == 0) iov[0].iov_len = 1; iov[0].iov_base = buff; iov[1].iov_len = read_size - iov[0].iov_len; iov[1].iov_base = buff + iov[0].iov_len; sendit = rtp_send_data_iov(session, cur_pos, 97, 0, 0, NULL, iov, read_size > iov[0].iov_len ? 2 : 1, NULL, 0, 0, 0); } #endif if (sendit < 0) { printf("rtp_send_data error\n"); exit(1); } if (do_rtcp) rtp_send_ctrl(session, cur_pos, NULL); printf("set timestamp = "U64", size %u\n", cur_pos, read_size); cur_pos += read_size; packet_size++; number_of_packet++; //rtp_periodic(); //rtp_send_ctrl(session,cur_pos,NULL); rtp_update(session); // Some sort of sleep here... usleep(2 * 1000); } printf("I've sent %d RTP packets!\n\n", number_of_packet); close(fd); if (rtcp_file != NULL) fclose(rtcp_file); rtp_done(session); return 0; }
/* DTLS-SRTP initialization */ gint janus_dtls_srtp_init(const char *server_pem, const char *server_key, const char *password) { const char *crypto_lib = NULL; #if JANUS_USE_OPENSSL_PRE_1_1_API #if defined(LIBRESSL_VERSION_NUMBER) crypto_lib = "LibreSSL"; #else crypto_lib = "OpenSSL pre-1.1.0"; #endif /* First of all make OpenSSL thread safe (see note above on issue #316) */ janus_dtls_locks = g_malloc0(sizeof(*janus_dtls_locks) * CRYPTO_num_locks()); int l=0; for(l = 0; l < CRYPTO_num_locks(); l++) { janus_mutex_init(&janus_dtls_locks[l]); } CRYPTO_THREADID_set_callback(janus_dtls_cb_openssl_threadid); CRYPTO_set_locking_callback(janus_dtls_cb_openssl_lock); #else crypto_lib = "OpenSSL >= 1.1.0"; #endif #ifdef HAVE_BORINGSSL crypto_lib = "BoringSSL"; #endif JANUS_LOG(LOG_INFO, "Crypto: %s\n", crypto_lib); #ifndef HAVE_SRTP_AESGCM JANUS_LOG(LOG_WARN, "The libsrtp installation does not support AES-GCM profiles\n"); #endif /* Go on and create the DTLS context */ #if JANUS_USE_OPENSSL_PRE_1_1_API ssl_ctx = SSL_CTX_new(DTLSv1_method()); #else ssl_ctx = SSL_CTX_new(DTLS_method()); #endif if(!ssl_ctx) { JANUS_LOG(LOG_FATAL, "Ops, error creating DTLS context?\n"); return -1; } SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, janus_dtls_verify_callback); SSL_CTX_set_tlsext_use_srtp(ssl_ctx, #ifdef HAVE_SRTP_AESGCM "SRTP_AEAD_AES_256_GCM:SRTP_AEAD_AES_128_GCM:SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32"); #else "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32"); #endif if(!server_pem && !server_key) { JANUS_LOG(LOG_WARN, "No cert/key specified, autogenerating some...\n"); if(janus_dtls_generate_keys(&ssl_cert, &ssl_key) != 0) { JANUS_LOG(LOG_FATAL, "Error generating DTLS key/certificate\n"); return -2; } } else if(!server_pem || !server_key) { JANUS_LOG(LOG_FATAL, "DTLS certificate and key must be specified\n"); return -2; } else if(janus_dtls_load_keys(server_pem, server_key, password, &ssl_cert, &ssl_key) != 0) { return -3; } if(!SSL_CTX_use_certificate(ssl_ctx, ssl_cert)) { JANUS_LOG(LOG_FATAL, "Certificate error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -4; } if(!SSL_CTX_use_PrivateKey(ssl_ctx, ssl_key)) { JANUS_LOG(LOG_FATAL, "Certificate key error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -5; } if(!SSL_CTX_check_private_key(ssl_ctx)) { JANUS_LOG(LOG_FATAL, "Certificate check error (%s)\n", ERR_reason_error_string(ERR_get_error())); return -6; } SSL_CTX_set_read_ahead(ssl_ctx,1); unsigned int size; unsigned char fingerprint[EVP_MAX_MD_SIZE]; if(X509_digest(ssl_cert, EVP_sha256(), (unsigned char *)fingerprint, &size) == 0) { JANUS_LOG(LOG_FATAL, "Error converting X509 structure (%s)\n", ERR_reason_error_string(ERR_get_error())); return -7; } char *lfp = (char *)&local_fingerprint; unsigned int i = 0; for(i = 0; i < size; i++) { g_snprintf(lfp, 4, "%.2X:", fingerprint[i]); lfp += 3; } *(lfp-1) = 0; JANUS_LOG(LOG_INFO, "Fingerprint of our certificate: %s\n", local_fingerprint); SSL_CTX_set_cipher_list(ssl_ctx, DTLS_CIPHERS); if(janus_dtls_bio_filter_init() < 0) { JANUS_LOG(LOG_FATAL, "Error initializing BIO filter\n"); return -8; } /* Initialize libsrtp */ if(srtp_init() != srtp_err_status_ok) { JANUS_LOG(LOG_FATAL, "Ops, error setting up libsrtp?\n"); return 5; } return 0; }
err_status_t ortp_srtp_init(void) { return srtp_init(); }
err_status_t ortp_srtp_init(void) { ortp_message("srtp init"); return srtp_init(); }
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; 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; char *address = NULL; char key[MAX_KEY_LEN]; unsigned short port = 0; rtp_sender_t snd; srtp_policy_t policy; err_status_t status; int 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 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, "k:rsgt:ae:ld:"); if (c == -1) { break; } switch (c) { 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 = crypto_kernel_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; default: usage(argv[0]); } } if (prog_type == unknown) { if (do_list_mods) { status = crypto_kernel_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); } 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 OPENSSL switch (key_size) { case 128: crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp); crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp); break; case 256: crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp); crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp); break; } #else printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n"); return 0; #endif } else { switch (key_size) { case 128: crypto_policy_set_rtp_default(&policy.rtp); crypto_policy_set_rtcp_default(&policy.rtcp); break; case 256: crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp); 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: crypto_policy_set_aes_cm_128_null_auth(&policy.rtp); crypto_policy_set_rtcp_default(&policy.rtcp); break; case 256: crypto_policy_set_aes_cm_256_null_auth(&policy.rtp); crypto_policy_set_rtcp_default(&policy.rtcp); break; } } break; case sec_serv_auth: if (gcm_on) { #ifdef OPENSSL switch (key_size) { case 128: crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp); crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp); break; case 256: crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp); 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 { crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp); 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 on command line into an octet string */ len = hex_string_to_octet_string(key, input_key, policy.rtp.cipher_key_len*2); /* check that hex string is the right length */ if (len < policy.rtp.cipher_key_len*2) { fprintf(stderr, "error: too few digits in key/salt " "(should be %d hexadecimal digits, found %d)\n", policy.rtp.cipher_key_len*2, 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); } 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. */ policy.key = (uint8_t *)key; policy.ssrc.type = ssrc_specific; policy.ssrc.value = ssrc; policy.rtp.cipher_type = NULL_CIPHER; policy.rtp.cipher_key_len = 0; policy.rtp.auth_type = NULL_AUTH; policy.rtp.auth_key_len = 0; policy.rtp.auth_tag_len = 0; policy.rtp.sec_serv = sec_serv_none; policy.rtcp.cipher_type = NULL_CIPHER; policy.rtcp.cipher_key_len = 0; policy.rtcp.auth_type = NULL_AUTH; policy.rtcp.auth_key_len = 0; policy.rtcp.auth_tag_len = 0; policy.rtcp.sec_serv = sec_serv_none; 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; }
/* * Here's the entry point */ int main (int argc, char *argv[]) { int sock; char *filenm = NULL; struct in_addr rcvr_addr; program_type prog_type = unknown; sec_serv_t sec_servs = sec_serv_conf | sec_serv_auth; int num_threads = 1; int c; char *input_key = NULL; char *address = NULL; char key[MAX_KEY_LEN]; unsigned short start_port = 0; srtp_policy_t *policy; err_status_t status; thread_parms_t *tplist[MAX_THREADS_SUPPORTED]; thread_parms_t *tp; int i; pthread_attr_t t_attr; struct sched_param sp1 = { 11 }; int len; int rc; /* 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(argc, argv, "k:n:o:rs"); if (c == -1) { break; } switch (c) { case 'n': num_threads = atoi(optarg); if (num_threads > MAX_THREADS_SUPPORTED) { printf("error: maximum number of threads supported is %d\n", MAX_THREADS_SUPPORTED); exit(1); } printf("Running %d threads\n", num_threads); break; case 'k': input_key = optarg; printf("Using key\n"); break; case 'o': filenm = optarg; printf("Using output file: %s\n", filenm); break; case 'r': prog_type = receiver; break; case 's': prog_type = sender; break; default: usage(argv[0]); } } if (prog_type == unknown) { printf("error: neither sender [-s] nor receiver [-r] specified\n"); usage(argv[0]); } if (!input_key) { /* * a key must be provided if and only if security services have * been requested */ usage(argv[0]); } if (argc != optind + 2) { /* wrong number of arguments */ usage(argv[0]); } /* get IP address from arg */ address = argv[optind++]; /* * read key from hexadecimal on command line into an octet string */ len = hex_string_to_octet_string(key, input_key, MASTER_KEY_LEN * 2); /* check that hex string is the right length */ if (len < MASTER_KEY_LEN * 2) { fprintf(stderr, "error: too few digits in key/salt " "(should be %d hexadecimal digits, found %d)\n", MASTER_KEY_LEN * 2, len); exit(1); } if (strlen(input_key) > MASTER_KEY_LEN * 2) { fprintf(stderr, "error: too many digits in key/salt " "(should be %d hexadecimal digits, found %u)\n", MASTER_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)); /* get starting port from arg */ start_port = atoi(argv[optind++]); /* set address */ 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); } if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) { printf("\nMulticast addresses not supported\n"); exit(1); } if (prog_type == receiver && filenm != NULL) { output = fopen(filenm, "wa"); if (output == NULL) { printf("\nUnable to open output file.\n"); exit(1); } } else { output = stdout; } /* * Setup and kick-off each thread. Each thread will be either * a receiver or a sender, depending on the arguments passed to us */ for (i = 0; i < num_threads; i++) { /* open socket */ sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { int err; err = errno; fprintf(stderr, "%s: couldn't open socket: %d\n", argv[0], err); exit(1); } /* * Create an SRTP policy */ policy = malloc(sizeof(srtp_policy_t)); if (policy == NULL) { fprintf(stderr, "Unable to malloc\n"); exit(1); } crypto_policy_set_rtp_default(&policy->rtp); crypto_policy_set_rtcp_default(&policy->rtcp); policy->ssrc.type = ssrc_specific; policy->ssrc.value = SSRC_BASE; policy->key = (uint8_t*)key; policy->next = NULL; policy->rtp.sec_serv = sec_servs; policy->rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */ /* * Create a thread_parms_t instance to manage this thread */ tplist[i] = malloc(sizeof(thread_parms_t)); if (tplist[i] == NULL) { fprintf(stderr, "Unable to malloc\n"); exit(1); } tp = tplist[i]; tp->thread_num = i; tp->sock = sock; tp->port = start_port + i; tp->policy = policy; tp->name.sin_addr = rcvr_addr; tp->name.sin_family = PF_INET; tp->name.sin_port = htons(start_port + i); tp->ssrc = SSRC_BASE; tp->stream_cnt = NUM_SSRC_PER_THREAD; //Number of streams to create for the session /* * Setup the pthread attributes */ pthread_attr_init(&t_attr); pthread_attr_setschedparam(&t_attr, &sp1); pthread_attr_setschedpolicy(&t_attr, SCHED_RR); if (prog_type == sender) { /* * Start a sender thread */ rc = pthread_create(&tp->thread_id, &t_attr, sender_thread, tp); if (rc) { fprintf(stderr, "Unable to create thread\n"); exit(1); } } else { /* prog_type == receiver */ /* * Start a receiver thread */ rc = pthread_create(&tp->thread_id, &t_attr, receiver_thread, tp); if (rc) { fprintf(stderr, "Unable to create thread\n"); exit(1); } } /* * Clean-up the attributes */ pthread_attr_destroy(&t_attr); } /* * Wait for all threads to finish */ for (i = 0; i < num_threads; i++) { void *res; tp = tplist[i]; pthread_join(tp->thread_id, &res); close(tplist[i]->sock); free(tplist[i]->policy); free(tplist[i]); } /* * If we don't call this, we get a memory leak in the * libsrtp libary */ status = srtp_shutdown(); if (status) { printf("error: srtp shutdown failed with error code %d\n", status); exit(1); } return (0); }