static void janus_dtls_srtp_free(const janus_refcount *dtls_ref) { janus_dtls_srtp *dtls = janus_refcount_containerof(dtls_ref, janus_dtls_srtp, ref); /* This stack can be destroyed, free all the resources */ dtls->component = NULL; if(dtls->ssl != NULL) { SSL_free(dtls->ssl); dtls->ssl = NULL; } /* BIOs are destroyed by SSL_free */ dtls->read_bio = NULL; dtls->write_bio = NULL; dtls->filter_bio = NULL; if(dtls->srtp_valid) { if(dtls->srtp_in) { srtp_dealloc(dtls->srtp_in); dtls->srtp_in = NULL; } if(dtls->srtp_out) { srtp_dealloc(dtls->srtp_out); dtls->srtp_out = NULL; } /* FIXME What about dtls->remote_policy and dtls->local_policy? */ } g_free(dtls); dtls = NULL; }
void janus_dtls_srtp_destroy(janus_dtls_srtp *dtls) { if(dtls == NULL) return; #ifdef HAVE_SCTP /* Destroy the SCTP association if this is a DataChannel */ if(dtls->sctp != NULL) { janus_sctp_association_destroy(dtls->sctp); dtls->sctp = NULL; } #endif /* Destroy DTLS stack and free resources */ dtls->component = NULL; if(dtls->ssl != NULL) { SSL_free(dtls->ssl); dtls->ssl = NULL; } /* BIOs are destroyed by SSL_free */ dtls->read_bio = NULL; dtls->write_bio = NULL; dtls->filter_bio = NULL; if(dtls->srtp_valid) { if(dtls->srtp_in) { srtp_dealloc(dtls->srtp_in); dtls->srtp_in = NULL; } if(dtls->srtp_out) { srtp_dealloc(dtls->srtp_out); dtls->srtp_out = NULL; } /* FIXME What about dtls->remote_policy and dtls->local_policy? */ } g_free(dtls); dtls = NULL; }
/* * Stop SRTP session. */ PJ_DEF(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp) { transport_srtp *p_srtp = (transport_srtp*) srtp; err_status_t err; PJ_ASSERT_RETURN(srtp, PJ_EINVAL); if (!p_srtp->session_inited) return PJ_SUCCESS; err = srtp_dealloc(p_srtp->srtp_rx_ctx); if (err != err_status_ok) { PJ_LOG(4, (p_srtp->pool->obj_name, "Failed to dealloc RX SRTP context: %s", get_libsrtp_errstr(err))); } err = srtp_dealloc(p_srtp->srtp_tx_ctx); if (err != err_status_ok) { PJ_LOG(4, (p_srtp->pool->obj_name, "Failed to dealloc TX SRTP context: %s", get_libsrtp_errstr(err))); } p_srtp->session_inited = PJ_FALSE; return PJ_SUCCESS; }
/* * Stop SRTP session. */ PJ_DEF(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp) { transport_srtp *p_srtp = (transport_srtp*) srtp; err_status_t err; PJ_ASSERT_RETURN(srtp, PJ_EINVAL); pj_lock_acquire(p_srtp->mutex); if (!p_srtp->session_inited) { pj_lock_release(p_srtp->mutex); return PJ_SUCCESS; } err = srtp_dealloc(p_srtp->srtp_rx_ctx); if (err != err_status_ok) { PJ_LOG(4, (p_srtp->pool->obj_name, "Failed to dealloc RX SRTP context: %s", get_libsrtp_errstr(err))); } err = srtp_dealloc(p_srtp->srtp_tx_ctx); if (err != err_status_ok) { PJ_LOG(4, (p_srtp->pool->obj_name, "Failed to dealloc TX SRTP context: %s", get_libsrtp_errstr(err))); } p_srtp->session_inited = PJ_FALSE; pj_bzero(&p_srtp->rx_policy, sizeof(p_srtp->rx_policy)); pj_bzero(&p_srtp->tx_policy, sizeof(p_srtp->tx_policy)); pj_lock_release(p_srtp->mutex); return PJ_SUCCESS; }
void janus_dtls_srtp_destroy(janus_dtls_srtp *dtls) { if(dtls == NULL) return; /* Destroy DTLS stack and free resources */ dtls->component = NULL; if(dtls->ssl != NULL) { SSL_free(dtls->ssl); dtls->ssl = NULL; } /* BIOs are destroyed by SSL_free */ dtls->read_bio = NULL; dtls->write_bio = NULL; if(dtls->srtp_valid) { if(dtls->remote_policy.key != NULL) { g_free(dtls->remote_policy.key); dtls->remote_policy.key = NULL; } if(dtls->local_policy.key != NULL) { g_free(dtls->local_policy.key); dtls->local_policy.key = NULL; } srtp_dealloc(dtls->srtp_in); srtp_dealloc(dtls->srtp_out); /* FIXME What about dtls->remote_policy and dtls->local_policy? */ } if(dtls->dtls_last_msg != NULL) { g_free(dtls->dtls_last_msg); dtls->dtls_last_msg = NULL; } g_free(dtls); dtls = NULL; }
SrtpChannel::~SrtpChannel() { active_ = false; ELOG_DEBUG("Deallocating SRTP sessions"); if (send_session_ != NULL) { srtp_dealloc(send_session_); } if (receive_session_ != NULL) { srtp_dealloc(receive_session_); } }
/** * Switch off the security for the defined part. * * @param ctx * Pointer to the opaque ZrtpContext structure. * @param part Defines for which part (sender or receiver) to * switch off security */ static void ozrtp_srtpSecretsOff (ZrtpContext* ctx, int32_t part ) { OrtpZrtpContext *userData = user_data(ctx); if (userData->srtpRecv != NULL) { srtp_dealloc(userData->srtpRecv); userData->srtpRecv=NULL; } if (userData->srtpSend != NULL) { srtp_dealloc(userData->srtpSend); userData->srtpSend=NULL; } ortp_message("ZRTP secrets off"); }
void ortp_zrtp_context_destroy(OrtpZrtpContext *ctx) { ortp_message("Stopping ZRTP context"); zrtp_stopZrtpEngine(ctx->zrtpContext); ortp_message("Destroying ZRTP wrapper"); zrtp_DestroyWrapper(ctx->zrtpContext); ortp_message("Destroying ORTP-ZRTP mutex"); ortp_mutex_destroy(&ctx->mutex); ortp_message("Destroying SRTP contexts"); if (ctx->srtpSend != NULL) srtp_dealloc(ctx->srtpSend); if (ctx->srtpRecv != NULL) srtp_dealloc(ctx->srtpRecv); ortp_message("ORTP-ZRTP context destroyed"); }
srtpw_err_status_t srtpw_srtp_destroy(srtpw_srtp *srtp) { if ((srtp_t)srtp) { srtp_dealloc((srtp_t)srtp); } return srtpw_err_status_ok; }
static void destructor(void *arg) { struct menc_st *st = arg; mem_deref(st->sdpm); mem_deref(st->crypto_suite); /* note: must be done before freeing socket */ mem_deref(st->uh_rtp); mem_deref(st->uh_rtcp); mem_deref(st->rtpsock); mem_deref(st->rtcpsock); if (st->srtp_tx) srtp_dealloc(st->srtp_tx); if (st->srtp_rx) srtp_dealloc(st->srtp_rx); }
void * sender_thread (void *arg) { err_status_t status; thread_parms_t *tp = (thread_parms_t*)arg; rtp_sender_t snd[NUM_SSRC_PER_THREAD]; int cnt = 0; int i; srtp_ctx_t *srtp_ctx = NULL; printf("\nStarting sender thread (port: %d base-ssrc: %x stream_cnt: %d)\n", tp->port, tp->ssrc, tp->stream_cnt); /* initialize sender's rtp and srtp contexts */ status = srtp_create(&srtp_ctx, tp->policy); if (status) { fprintf(stderr, "error: srtp_create() failed with code %d\n", status); exit(1); } /* now add the streams on the session */ for (i = 0; i < tp->stream_cnt; i++) { rtp_sender_init(&snd[i], tp->sock, tp->name, tp->ssrc); snd[i].srtp_ctx = srtp_ctx; status = srtp_add_stream(snd[i].srtp_ctx, tp->policy); if (status) { fprintf(stderr, "error: srtp_add_stream() failed with code %d\n", status); exit(1); } tp->policy->ssrc.value++; tp->ssrc++; } while (cnt < THREAD_PKT_CNT) { for (i = 0; i < tp->stream_cnt; i++) { rtp_sendto(&snd[i], test_data, DATA_LEN); cnt++; if (cnt % STAT_WINDOW == 0) { printf("Thread id %d transmit count is %d\n", tp->thread_num, cnt); } } usleep(SLEEP_LEN); } /* * Clean up the session */ srtp_dealloc(srtp_ctx); return NULL; }
int trtp_srtp_ctx_deinit(trtp_srtp_ctx_xt* ctx){ if(!ctx){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(ctx->initialized){ /*err_status_t srtp_err =*/ srtp_dealloc(ctx->session); memset(&ctx->policy, 0, sizeof(ctx->policy)); ctx->initialized = tsk_false; } return 0; }
void evrb_crypto_free(void* ctx) { EVRB_CRYPTO* evb_crypto=ctx; if(evb_crypto) { srtp_dealloc(evb_crypto->srtp_session); if (evb_crypto->key) free(evb_crypto->key); evb_crypto->key=0; if (evb_crypto->dh) dh_free(evb_crypto->dh); free(ctx); ctx=0; } }
JNIEXPORT jint JNICALL Java_org_theonionphone_protocol_SrtpProtocol_deinit (JNIEnv *env, jobject obj) { err_status_t status = srtp_dealloc((*srtpContextSend)); if(status) { return status; } status = srtp_dealloc((*srtpContextRecv)); if(status) { return status; } status = srtp_deinit(); if(status) { return status; } free(srtpContextSend); free(srtpContextRecv); return status; }
err_status_t srtp_print_policy(const srtp_policy_t *policy) { err_status_t status; srtp_t session; status = srtp_create(&session, policy); if (status) return status; status = srtp_session_print_policy(session); if (status) return status; status = srtp_dealloc(session); if (status) return status; return err_status_ok; }
/* Clear the policy list */ static void gst_srtp_dec_clear_streams (GstSrtpDec * filter) { guint nb = 0; GST_OBJECT_LOCK (filter); if (!filter->first_session) srtp_dealloc (filter->session); if (filter->streams) nb = g_hash_table_foreach_remove (filter->streams, remove_yes, NULL); filter->first_session = TRUE; GST_OBJECT_UNLOCK (filter); GST_DEBUG_OBJECT (filter, "Cleared %d streams", nb); }
err_status_t ortp_srtp_dealloc(srtp_t session) { return srtp_dealloc(session); }
int rtp_decoder_deinit_srtp(rtp_decoder_t decoder) { return srtp_dealloc(decoder->srtp_ctx); }
/* * Initialize and start SRTP session with the given parameters. */ PJ_DEF(pj_status_t) pjmedia_transport_srtp_start( pjmedia_transport *tp, const pjmedia_srtp_crypto *tx, const pjmedia_srtp_crypto *rx) { transport_srtp *srtp = (transport_srtp*) tp; srtp_policy_t tx_; srtp_policy_t rx_; err_status_t err; int cr_tx_idx = 0; int au_tx_idx = 0; int cr_rx_idx = 0; int au_rx_idx = 0; pj_status_t status = PJ_SUCCESS; PJ_ASSERT_RETURN(tp && tx && rx, PJ_EINVAL); pj_lock_acquire(srtp->mutex); if (srtp->session_inited) { pjmedia_transport_srtp_stop(tp); } /* Get encryption and authentication method */ cr_tx_idx = au_tx_idx = get_crypto_idx(&tx->name); if (tx->flags & PJMEDIA_SRTP_NO_ENCRYPTION) cr_tx_idx = 0; if (tx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION) au_tx_idx = 0; cr_rx_idx = au_rx_idx = get_crypto_idx(&rx->name); if (rx->flags & PJMEDIA_SRTP_NO_ENCRYPTION) cr_rx_idx = 0; if (rx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION) au_rx_idx = 0; /* Check whether the crypto-suite requested is supported */ if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 || au_rx_idx == -1) { status = PJMEDIA_SRTP_ENOTSUPCRYPTO; goto on_return; } /* If all options points to 'NULL' method, just bypass SRTP */ if (cr_tx_idx == 0 && cr_rx_idx == 0 && au_tx_idx == 0 && au_rx_idx == 0) { srtp->bypass_srtp = PJ_TRUE; goto on_return; } /* Check key length */ if (tx->key.slen != (pj_ssize_t)crypto_suites[cr_tx_idx].cipher_key_len || rx->key.slen != (pj_ssize_t)crypto_suites[cr_rx_idx].cipher_key_len) { status = PJMEDIA_SRTP_EINKEYLEN; goto on_return; } /* Init transmit direction */ pj_bzero(&tx_, sizeof(srtp_policy_t)); pj_memmove(srtp->tx_key, tx->key.ptr, tx->key.slen); if (cr_tx_idx && au_tx_idx) tx_.rtp.sec_serv = sec_serv_conf_and_auth; else if (cr_tx_idx) tx_.rtp.sec_serv = sec_serv_conf; else if (au_tx_idx) tx_.rtp.sec_serv = sec_serv_auth; else tx_.rtp.sec_serv = sec_serv_none; tx_.key = (uint8_t*)srtp->tx_key; tx_.ssrc.type = ssrc_any_outbound; tx_.ssrc.value = 0; tx_.rtp.cipher_type = crypto_suites[cr_tx_idx].cipher_type; tx_.rtp.cipher_key_len = crypto_suites[cr_tx_idx].cipher_key_len; tx_.rtp.auth_type = crypto_suites[au_tx_idx].auth_type; tx_.rtp.auth_key_len = crypto_suites[au_tx_idx].auth_key_len; tx_.rtp.auth_tag_len = crypto_suites[au_tx_idx].srtp_auth_tag_len; tx_.rtcp = tx_.rtp; tx_.rtcp.auth_tag_len = crypto_suites[au_tx_idx].srtcp_auth_tag_len; tx_.next = NULL; err = srtp_create(&srtp->srtp_tx_ctx, &tx_); if (err != err_status_ok) { status = PJMEDIA_ERRNO_FROM_LIBSRTP(err); goto on_return; } srtp->tx_policy = *tx; pj_strset(&srtp->tx_policy.key, srtp->tx_key, tx->key.slen); srtp->tx_policy.name=pj_str(crypto_suites[get_crypto_idx(&tx->name)].name); /* Init receive direction */ pj_bzero(&rx_, sizeof(srtp_policy_t)); pj_memmove(srtp->rx_key, rx->key.ptr, rx->key.slen); if (cr_rx_idx && au_rx_idx) rx_.rtp.sec_serv = sec_serv_conf_and_auth; else if (cr_rx_idx) rx_.rtp.sec_serv = sec_serv_conf; else if (au_rx_idx) rx_.rtp.sec_serv = sec_serv_auth; else rx_.rtp.sec_serv = sec_serv_none; rx_.key = (uint8_t*)srtp->rx_key; rx_.ssrc.type = ssrc_any_inbound; rx_.ssrc.value = 0; rx_.rtp.sec_serv = crypto_suites[cr_rx_idx].service; rx_.rtp.cipher_type = crypto_suites[cr_rx_idx].cipher_type; rx_.rtp.cipher_key_len = crypto_suites[cr_rx_idx].cipher_key_len; rx_.rtp.auth_type = crypto_suites[au_rx_idx].auth_type; rx_.rtp.auth_key_len = crypto_suites[au_rx_idx].auth_key_len; rx_.rtp.auth_tag_len = crypto_suites[au_rx_idx].srtp_auth_tag_len; rx_.rtcp = rx_.rtp; rx_.rtcp.auth_tag_len = crypto_suites[au_rx_idx].srtcp_auth_tag_len; rx_.next = NULL; err = srtp_create(&srtp->srtp_rx_ctx, &rx_); if (err != err_status_ok) { srtp_dealloc(srtp->srtp_tx_ctx); status = PJMEDIA_ERRNO_FROM_LIBSRTP(err); goto on_return; } srtp->rx_policy = *rx; pj_strset(&srtp->rx_policy.key, srtp->rx_key, rx->key.slen); srtp->rx_policy.name=pj_str(crypto_suites[get_crypto_idx(&rx->name)].name); /* Declare SRTP session initialized */ srtp->session_inited = PJ_TRUE; /* Logging stuffs */ #if PJ_LOG_MAX_LEVEL >= 5 { char b64[PJ_BASE256_TO_BASE64_LEN(MAX_KEY_LEN)]; int b64_len; /* TX crypto and key */ b64_len = sizeof(b64); status = pj_base64_encode((pj_uint8_t*)tx->key.ptr, tx->key.slen, b64, &b64_len); if (status != PJ_SUCCESS) b64_len = pj_ansi_sprintf(b64, "--key too long--"); else b64[b64_len] = '\0'; PJ_LOG(5, (srtp->pool->obj_name, "TX: %s key=%s", srtp->tx_policy.name.ptr, b64)); if (srtp->tx_policy.flags) { PJ_LOG(5,(srtp->pool->obj_name, "TX: disable%s%s", (cr_tx_idx?"":" enc"), (au_tx_idx?"":" auth"))); } /* RX crypto and key */ b64_len = sizeof(b64); status = pj_base64_encode((pj_uint8_t*)rx->key.ptr, rx->key.slen, b64, &b64_len); if (status != PJ_SUCCESS) b64_len = pj_ansi_sprintf(b64, "--key too long--"); else b64[b64_len] = '\0'; PJ_LOG(5, (srtp->pool->obj_name, "RX: %s key=%s", srtp->rx_policy.name.ptr, b64)); if (srtp->rx_policy.flags) { PJ_LOG(5,(srtp->pool->obj_name,"RX: disable%s%s", (cr_rx_idx?"":" enc"), (au_rx_idx?"":" auth"))); } } #endif on_return: pj_lock_release(srtp->mutex); return status; }
SrtpFlow::~SrtpFlow() { if (session_) { srtp_dealloc(session_); } }
srtp_err_status_t test_dtls_srtp(void) { srtp_hdr_t *test_packet; int test_packet_len = 80; srtp_t s; srtp_policy_t policy; uint8_t key[SRTP_MAX_KEY_LEN]; uint8_t salt[SRTP_MAX_KEY_LEN]; unsigned int key_len, salt_len; srtp_profile_t profile; srtp_err_status_t err; /* create a 'null' SRTP session */ err = srtp_create(&s, NULL); if (err) return err; /* * verify that packet-processing functions behave properly - we * expect that these functions will return srtp_err_status_no_ctx */ test_packet = srtp_create_test_packet(80, 0xa5a5a5a5); if (test_packet == NULL) return srtp_err_status_alloc_fail; err = srtp_protect(s, test_packet, &test_packet_len); if (err != srtp_err_status_no_ctx) { printf("wrong return value from srtp_protect() (got code %d)\n", err); return srtp_err_status_fail; } err = srtp_unprotect(s, test_packet, &test_packet_len); if (err != srtp_err_status_no_ctx) { printf("wrong return value from srtp_unprotect() (got code %d)\n", err); return srtp_err_status_fail; } err = srtp_protect_rtcp(s, test_packet, &test_packet_len); if (err != srtp_err_status_no_ctx) { printf("wrong return value from srtp_protect_rtcp() (got code %d)\n", err); return srtp_err_status_fail; } err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len); if (err != srtp_err_status_no_ctx) { printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n", err); return srtp_err_status_fail; } /* * set keys to known values for testing */ profile = srtp_profile_aes128_cm_sha1_80; key_len = srtp_profile_get_master_key_length(profile); salt_len = srtp_profile_get_master_salt_length(profile); memset(key, 0xff, key_len); memset(salt, 0xee, salt_len); srtp_append_salt_to_key(key, key_len, salt, salt_len); policy.key = key; /* initialize SRTP policy from profile */ err = srtp_crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile); if (err) return err; err = srtp_crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile); if (err) return err; policy.ssrc.type = ssrc_any_inbound; policy.ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; err = srtp_add_stream(s, &policy); if (err) return err; err = srtp_dealloc(s); if (err) return err; free(test_packet); return srtp_err_status_ok; }
/* * Initialize and start SRTP session with the given parameters. */ PJ_DEF(pj_status_t) pjmedia_transport_srtp_start( pjmedia_transport *tp, const pjmedia_srtp_crypto *tx, const pjmedia_srtp_crypto *rx) { transport_srtp *srtp = (transport_srtp*) tp; srtp_policy_t tx_; srtp_policy_t rx_; err_status_t err; int cr_tx_idx = 0; int au_tx_idx = 0; int cr_rx_idx = 0; int au_rx_idx = 0; int crypto_suites_cnt; PJ_ASSERT_RETURN(tp && tx && rx, PJ_EINVAL); if (srtp->session_inited) { pjmedia_transport_srtp_stop(tp); } crypto_suites_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]); /* Get encryption and authentication method */ cr_tx_idx = au_tx_idx = get_crypto_idx(&tx->name); if (tx->flags & PJMEDIA_SRTP_NO_ENCRYPTION) cr_tx_idx = 0; if (tx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION) au_tx_idx = 0; cr_rx_idx = au_rx_idx = get_crypto_idx(&rx->name); if (rx->flags & PJMEDIA_SRTP_NO_ENCRYPTION) cr_rx_idx = 0; if (rx->flags & PJMEDIA_SRTP_NO_AUTHENTICATION) au_rx_idx = 0; /* Check whether the crypto-suite requested is supported */ if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 || au_rx_idx == -1) return PJMEDIA_SRTP_ENOTSUPCRYPTO; /* If all options points to 'NULL' method, just bypass SRTP */ if (cr_tx_idx == 0 && cr_rx_idx == 0 && au_tx_idx == 0 && au_rx_idx == 0) { srtp->bypass_srtp = PJ_TRUE; return PJ_SUCCESS; } /* Check key length */ if (tx->key.slen != (pj_ssize_t)crypto_suites[cr_tx_idx].cipher_key_len || rx->key.slen != (pj_ssize_t)crypto_suites[cr_rx_idx].cipher_key_len) return PJMEDIA_SRTP_EINKEYLEN; /* Init transmit direction */ pj_bzero(&tx_, sizeof(srtp_policy_t)); pj_memmove(srtp->tx_key, tx->key.ptr, tx->key.slen); if (cr_tx_idx && au_tx_idx) tx_.rtp.sec_serv = sec_serv_conf_and_auth; else if (cr_tx_idx) tx_.rtp.sec_serv = sec_serv_conf; else if (au_tx_idx) tx_.rtp.sec_serv = sec_serv_auth; else tx_.rtp.sec_serv = sec_serv_none; tx_.key = (uint8_t*)srtp->tx_key; tx_.ssrc.type = ssrc_any_outbound; tx_.ssrc.value = 0; tx_.rtp.cipher_type = crypto_suites[cr_tx_idx].cipher_type; tx_.rtp.cipher_key_len = crypto_suites[cr_tx_idx].cipher_key_len; tx_.rtp.auth_type = crypto_suites[au_tx_idx].auth_type; tx_.rtp.auth_key_len = crypto_suites[au_tx_idx].auth_key_len; tx_.rtp.auth_tag_len = crypto_suites[au_tx_idx].srtp_auth_tag_len; tx_.rtcp = tx_.rtp; tx_.rtcp.auth_tag_len = crypto_suites[au_tx_idx].srtcp_auth_tag_len; tx_.next = NULL; err = srtp_create(&srtp->srtp_tx_ctx, &tx_); if (err != err_status_ok) { return PJMEDIA_ERRNO_FROM_LIBSRTP(err); } srtp->tx_policy = *tx; pj_strset(&srtp->tx_policy.key, srtp->tx_key, tx->key.slen); srtp->tx_policy.name=pj_str(crypto_suites[get_crypto_idx(&tx->name)].name); /* Init receive direction */ pj_bzero(&rx_, sizeof(srtp_policy_t)); pj_memmove(srtp->rx_key, rx->key.ptr, rx->key.slen); if (cr_rx_idx && au_rx_idx) rx_.rtp.sec_serv = sec_serv_conf_and_auth; else if (cr_rx_idx) rx_.rtp.sec_serv = sec_serv_conf; else if (au_rx_idx) rx_.rtp.sec_serv = sec_serv_auth; else rx_.rtp.sec_serv = sec_serv_none; rx_.key = (uint8_t*)srtp->rx_key; rx_.ssrc.type = ssrc_any_inbound; rx_.ssrc.value = 0; rx_.rtp.sec_serv = crypto_suites[cr_rx_idx].service; rx_.rtp.cipher_type = crypto_suites[cr_rx_idx].cipher_type; rx_.rtp.cipher_key_len = crypto_suites[cr_rx_idx].cipher_key_len; rx_.rtp.auth_type = crypto_suites[au_rx_idx].auth_type; rx_.rtp.auth_key_len = crypto_suites[au_rx_idx].auth_key_len; rx_.rtp.auth_tag_len = crypto_suites[au_rx_idx].srtp_auth_tag_len; rx_.rtcp = rx_.rtp; rx_.rtcp.auth_tag_len = crypto_suites[au_rx_idx].srtcp_auth_tag_len; rx_.next = NULL; err = srtp_create(&srtp->srtp_rx_ctx, &rx_); if (err != err_status_ok) { srtp_dealloc(srtp->srtp_tx_ctx); return PJMEDIA_ERRNO_FROM_LIBSRTP(err); } srtp->rx_policy = *rx; pj_strset(&srtp->rx_policy.key, srtp->rx_key, rx->key.slen); srtp->rx_policy.name=pj_str(crypto_suites[get_crypto_idx(&rx->name)].name); /* Declare SRTP session initialized */ srtp->session_inited = PJ_TRUE; PJ_LOG(5, (srtp->pool->obj_name, "TX: %s key=%s", srtp->tx_policy.name.ptr, octet_string_hex_string(tx->key.ptr, tx->key.slen))); if (srtp->tx_policy.flags) { PJ_LOG(5,(srtp->pool->obj_name,"TX: disable%s%s", (cr_tx_idx?"":" enc"), (au_tx_idx?"":" auth"))); } PJ_LOG(5, (srtp->pool->obj_name, "RX: %s key=%s", srtp->rx_policy.name.ptr, octet_string_hex_string(rx->key.ptr, rx->key.slen))); if (srtp->rx_policy.flags) { PJ_LOG(5,(srtp->pool->obj_name,"RX: disable%s%s", (cr_rx_idx?"":" enc"), (au_rx_idx?"":" auth"))); } return PJ_SUCCESS; }
err_status_t srtcp_test(const srtp_policy_t *policy) { int i; srtp_t srtcp_sender; srtp_t srtcp_rcvr; err_status_t status = err_status_ok; srtp_hdr_t *hdr, *hdr2; uint8_t hdr_enc[64]; uint8_t *pkt_end; int msg_len_octets, msg_len_enc; int len; int tag_length = policy->rtp.auth_tag_len; uint32_t ssrc; srtp_policy_t *rcvr_policy; err_check(srtp_create(&srtcp_sender, policy)); /* print out policy */ err_check(srtp_session_print_policy(srtcp_sender)); /* * initialize data buffer, using the ssrc in the policy unless that * value is a wildcard, in which case we'll just use an arbitrary * one */ if (policy->ssrc.type != ssrc_specific) ssrc = 0xdecafbad; else ssrc = policy->ssrc.value; msg_len_octets = 28; hdr = srtp_create_test_packet(msg_len_octets, ssrc); if (hdr == NULL) return err_status_alloc_fail; hdr2 = srtp_create_test_packet(msg_len_octets, ssrc); if (hdr2 == NULL) { free(hdr); return err_status_alloc_fail; } /* set message length */ len = msg_len_octets; debug_print(mod_driver, "before protection:\n%s", srtp_packet_to_string(hdr, len)); #if PRINT_REFERENCE_PACKET debug_print(mod_driver, "reference packet before protection:\n%s", octet_string_hex_string((uint8_t *)hdr, len)); #endif err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); debug_print(mod_driver, "after protection:\n%s", srtp_packet_to_string(hdr, len)); #if PRINT_REFERENCE_PACKET debug_print(mod_driver, "after protection:\n%s", octet_string_hex_string((uint8_t *)hdr, len)); #endif /* save protected message and length */ memcpy(hdr_enc, hdr, len); msg_len_enc = len; /* * check for overrun of the srtp_protect() function * * The packet is followed by a value of 0xfffff; if the value of the * data following the packet is different, then we know that the * protect function is overwriting the end of the packet. */ pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t) + msg_len_octets + tag_length; for (i = 0; i < 4; i++) if (pkt_end[i] != 0xff) { fprintf(stdout, "overwrite in srtp_protect_rtcp() function " "(expected %x, found %x in trailing octet %d)\n", 0xff, ((uint8_t *)hdr)[i], i); free(hdr); free(hdr2); return err_status_algo_fail; } /* * if the policy includes confidentiality, check that ciphertext is * different than plaintext * * Note that this check will give false negatives, with some small * probability, especially if the packets are short. For that * reason, we skip this check if the plaintext is less than four * octets long. */ if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) { printf("testing that ciphertext is distinct from plaintext..."); status = err_status_algo_fail; for (i=12; i < msg_len_octets+12; i++) if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { status = err_status_ok; } if (status) { printf("failed\n"); free(hdr); free(hdr2); return status; } printf("passed\n"); } /* * if the policy uses a 'wildcard' ssrc, then we need to make a copy * of the policy that changes the direction to inbound * * we always copy the policy into the rcvr_policy, since otherwise * the compiler would fret about the constness of the policy */ rcvr_policy = malloc(sizeof(srtp_policy_t)); if (rcvr_policy == NULL) return err_status_alloc_fail; memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); if (policy->ssrc.type == ssrc_any_outbound) { rcvr_policy->ssrc.type = ssrc_any_inbound; } err_check(srtp_create(&srtcp_rcvr, rcvr_policy)); err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len)); debug_print(mod_driver, "after unprotection:\n%s", srtp_packet_to_string(hdr, len)); /* verify that the unprotected packet matches the origial one */ for (i=0; i < msg_len_octets; i++) if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) { fprintf(stdout, "mismatch at octet %d\n", i); status = err_status_algo_fail; } if (status) { free(hdr); free(hdr2); return status; } /* * if the policy includes authentication, then test for false positives */ if (policy->rtp.sec_serv & sec_serv_auth) { char *data = ((char *)hdr) + 12; printf("testing for false positives in replay check..."); /* set message length */ len = msg_len_enc; /* unprotect a second time - should fail with a replay error */ status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len); if (status != err_status_replay_fail) { printf("failed with error code %d\n", status); free(hdr); free(hdr2); return status; } else { printf("passed\n"); } printf("testing for false positives in auth check..."); /* increment sequence number in header */ hdr->seq++; /* set message length */ len = msg_len_octets; /* apply protection */ err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len)); /* flip bits in packet */ data[0] ^= 0xff; /* unprotect, and check for authentication failure */ status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len); if (status != err_status_auth_fail) { printf("failed\n"); free(hdr); free(hdr2); return status; } else { printf("passed\n"); } } err_check(srtp_dealloc(srtcp_sender)); err_check(srtp_dealloc(srtcp_rcvr)); free(hdr); free(hdr2); return err_status_ok; }
int rtp_receiver_deinit_srtp(rtp_receiver_t sender) { return srtp_dealloc(sender->srtp_ctx); }
void * receiver_thread (void *arg) { err_status_t status; rtp_receiver_t rcvr[NUM_SSRC_PER_THREAD]; int cnt = 0; thread_parms_t *tp = (thread_parms_t*)arg; int len = DATA_LEN; char data[DATA_LEN + RTP_HEADER_LEN + 20]; //Adding 20 bytes for UDP header??? srtp_ctx_t *srtp_ctx = NULL; int i; printf("\nStarting receiver thread (port: %d base-ssrc: %x stream_cnt: %d)\n", tp->port, tp->ssrc, tp->stream_cnt); if (bind(tp->sock, (struct sockaddr*)&tp->name, sizeof(tp->name)) < 0) { close(tp->sock); pthread_mutex_lock(&t_mutex); fprintf(output, "receiver socket bind error\n"); fflush(output); pthread_mutex_unlock(&t_mutex); perror(NULL); exit(1); } status = srtp_create(&srtp_ctx, tp->policy); if (status) { pthread_mutex_lock(&t_mutex); fprintf(output, "error: srtp_create() failed with code %d\n", status); fflush(output); pthread_mutex_unlock(&t_mutex); exit(1); } /* now add the streams on the session */ for (i = 0; i < tp->stream_cnt; i++) { rtp_receiver_init(&rcvr[i], tp->sock, tp->name, tp->ssrc); rcvr[i].srtp_ctx = srtp_ctx; status = srtp_add_stream(rcvr[i].srtp_ctx, tp->policy); if (status) { pthread_mutex_lock(&t_mutex); fprintf(output, "error: srtp_add_stream() failed with code %d\n", status); fflush(output); pthread_mutex_unlock(&t_mutex); exit(1); } tp->policy->ssrc.value++; tp->ssrc++; } /* get next packet and loop */ while (cnt < THREAD_PKT_CNT) { len = DATA_LEN + RTP_HEADER_LEN + 20; if (rtp_recvfrom(&rcvr[0], data, &len) > -1) { cnt++; if (cnt % STAT_WINDOW == 0) { pthread_mutex_lock(&t_mutex); fprintf(output, "Thread id %d receive count is %d\n", tp->thread_num, cnt); fflush(output); pthread_mutex_unlock(&t_mutex); } } } /* * Clean up the session */ srtp_dealloc(srtp_ctx); return (NULL); }