Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
/*
 * 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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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_);
  }
}
Beispiel #7
0
/**
 * 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");
}
Beispiel #8
0
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");
}
Beispiel #9
0
srtpw_err_status_t srtpw_srtp_destroy(srtpw_srtp *srtp)
{
    if ((srtp_t)srtp)
    {
        srtp_dealloc((srtp_t)srtp);
    }
    return srtpw_err_status_ok;
}
Beispiel #10
0
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);
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
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;
	}
}
Beispiel #14
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;
}
Beispiel #16
0
/* 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);
}
Beispiel #17
0
err_status_t ortp_srtp_dealloc(srtp_t session)
{
	return srtp_dealloc(session);
}
Beispiel #18
0
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;
}
Beispiel #20
0
SrtpFlow::~SrtpFlow() {
  if (session_) {
    srtp_dealloc(session_);
  }
}
Beispiel #21
0
srtp_err_status_t
test_dtls_srtp(void) {
  srtp_hdr_t *test_packet;
  int test_packet_len = 80;
  srtp_t s;
  srtp_policy_t policy;
  uint8_t key[SRTP_MAX_KEY_LEN];
  uint8_t salt[SRTP_MAX_KEY_LEN];
  unsigned int key_len, salt_len;
  srtp_profile_t profile;
  srtp_err_status_t err;

  /* 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;
}
Beispiel #22
0
/*
 * 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;
}
Beispiel #23
0
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;
}
Beispiel #24
0
int
rtp_receiver_deinit_srtp(rtp_receiver_t sender) {
    return srtp_dealloc(sender->srtp_ctx);
}
Beispiel #25
0
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);
}