示例#1
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;
}
示例#2
0
err_status_t ortp_srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
{
	return srtp_add_stream(session, policy);
}
示例#3
0
/**
 * SRTP crypto data ready for the sender or receiver.
 *
 * The ZRTP implementation calls this method right after all SRTP
 * secrets are computed and ready to be used. The parameter points
 * to a structure that contains pointers to the SRTP secrets and a
 * <code>enum Role</code>. The called method (the implementation
 * of this abstract method) must either copy the pointers to the SRTP
 * data or the SRTP data itself to a save place. The SrtpSecret_t
 * structure is destroyed after the callback method returns to the
 * ZRTP implementation.
 *
 * The SRTP data themselves are obtained in the ZRtp object and are
 * valid as long as the ZRtp object is active. TheZRtp's
 * destructor clears the secrets. Thus the called method needs to
 * save the pointers only, ZRtp takes care of the data.
 *
 * The implementing class may enable SRTP processing in this
 * method or delay it to srtpSecertsOn().
 *
 * @param ctx
 *    Pointer to the opaque ZrtpContext structure.
 * @param secrets A pointer to a SrtpSecret_t structure that
 *     contains all necessary data.
 *
 * @param part for which part (Sender or Receiver) this data is
 *     valid.
 *
 * @return Returns false if something went wrong during
 *    initialization of SRTP context, for example memory shortage.
 */
static int32_t ozrtp_srtpSecretsReady (ZrtpContext* ctx, C_SrtpSecret_t* secrets, int32_t part ) {
	srtp_policy_t policy;
	err_status_t srtpCreateStatus;
	err_status_t addStreamStatus;
	OrtpZrtpContext *userData = user_data(ctx);

	ortp_message("ZRTP secrets for %s are ready; auth tag len is %i",
	             (part == ForSender) ? "sender" : "receiver",secrets->srtpAuthTagLen);

	// Get authentication and cipher algorithms in srtp format
	if (secrets->authAlgorithm != zrtp_Sha1) {
		ortp_fatal("unsupported authentication algorithm by srtp");
	}

	if (secrets->symEncAlgorithm != zrtp_Aes) {
		ortp_fatal("unsupported cipher algorithm by srtp");
	}

	/*
	 * Don't use crypto_policy_set_from_profile_for_rtp(), it is totally buggy.
	 */
	memset(&policy,0,sizeof(policy));

	if (secrets->srtpAuthTagLen == 32){
		crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
		crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtcp);
	}else if (secrets->srtpAuthTagLen == 80){
		crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
		crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
	}else{
		ortp_fatal("unsupported auth tag len");
	}

	if (part == ForSender) {
		srtpCreateStatus=srtp_create(&userData->srtpSend, NULL);
		policy.ssrc.type=ssrc_specific;
		policy.ssrc.value=userData->session->snd.ssrc; // us
		policy.key=key_with_salt(secrets, secrets->role);
		addStreamStatus=srtp_add_stream(userData->srtpSend, &policy);
	} else { //if (part == ForReceiver)
		srtpCreateStatus=srtp_create(&userData->srtpRecv, NULL);
		policy.ssrc.type = ssrc_any_inbound; /*we don't know the incoming ssrc will be */
		int32_t peerRole=secrets->role == Initiator ? Responder : Initiator;
		policy.key=key_with_salt(secrets,peerRole);
		addStreamStatus=srtp_add_stream(userData->srtpRecv, &policy);
	}

	ortp_free(policy.key);

	if (srtpCreateStatus != err_status_ok) {
		ortp_error("ZRTP Error %u during creation of SRTP context for %s",
			srtpCreateStatus, (part == ForSender) ? "sender" : "receiver");
		return 0;
	}
	if (addStreamStatus != err_status_ok) {
		ortp_error("ZRTP Error %u during addition of SRTP stream for %s",
			addStreamStatus, (part == ForSender) ? "sender" : "receiver");
		return 0;
	}
	return 1;
}
static int add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, const char* b64_key, bool_t inbound)
{
	srtp_policy_t policy;
	uint8_t* key;
	int key_size;
	err_status_t err;
	unsigned b64_key_length = strlen(b64_key);
	ssrc_t ssrc_conf;

	memset(&policy,0,sizeof(policy));

	switch(suite){
		case MS_AES_128_SHA1_32:
			crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
			// srtp doc says: not adapted to rtcp...
			crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtcp);
			break;
		case MS_AES_128_NO_AUTH:
			crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
			// srtp doc says: not adapted to rtcp...
			crypto_policy_set_aes_cm_128_null_auth(&policy.rtcp);
			break;
		case MS_NO_CIPHER_SHA1_80:
			crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
			crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtcp);
			break;
		case MS_AES_128_SHA1_80: /*default mode*/
			crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
			crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
			break;
		case MS_AES_256_SHA1_80:
			crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
			crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
			break;
		case MS_AES_256_SHA1_32:
			crypto_policy_set_aes_cm_256_hmac_sha1_32(&policy.rtp);
			crypto_policy_set_aes_cm_256_hmac_sha1_32(&policy.rtcp);
			break;
		case MS_CRYPTO_SUITE_INVALID:
			return -1;
			break;
	}
	key_size = b64_decode(b64_key, b64_key_length, 0, 0);
	if (key_size != policy.rtp.cipher_key_len) {
		ortp_error("Key size (%d) doesn't match the selected srtp profile (required %d)",
			key_size,
			policy.rtp.cipher_key_len);
			return -1;
	}
	key = (uint8_t*) ortp_malloc0(key_size+2); /*srtp uses padding*/
	if (b64_decode(b64_key, b64_key_length, key, key_size) != key_size) {
		ortp_error("Error decoding key");
		ortp_free(key);
		return -1;
	}
	if (!inbound)
		policy.allow_repeat_tx=1; /*necessary for telephone-events*/

	/*ssrc_conf.type=inbound ? ssrc_any_inbound : ssrc_specific;*/
	ssrc_conf.type=ssrc_specific;
	ssrc_conf.value=ssrc;

	policy.ssrc = ssrc_conf;
	policy.key = key;
	policy.next = NULL;

	err = srtp_add_stream(srtp, &policy);
	if (err != err_status_ok) {
		ortp_error("Failed to add stream to srtp session (%d)", err);
		ortp_free(key);
		return -1;
	}

	ortp_free(key);
	return 0;
}
示例#5
0
/* Create a stream in the session
 */
static err_status_t
init_session_stream (GstSrtpDec * filter, guint32 ssrc,
    GstSrtpDecSsrcStream * stream)
{
  err_status_t ret;
  srtp_policy_t policy;
  GstMapInfo map;
  guchar tmp[1];

  memset (&policy, 0, sizeof (srtp_policy_t));

  if (!stream)
    return err_status_bad_param;

  GST_INFO_OBJECT (filter, "Setting RTP policy...");
  set_crypto_policy_cipher_auth (stream->rtp_cipher, stream->rtp_auth,
      &policy.rtp);
  GST_INFO_OBJECT (filter, "Setting RTCP policy...");
  set_crypto_policy_cipher_auth (stream->rtcp_cipher, stream->rtcp_auth,
      &policy.rtcp);

  if (stream->key) {
    gst_buffer_map (stream->key, &map, GST_MAP_READ);
    policy.key = (guchar *) map.data;
  } else {
    policy.key = tmp;
  }

  policy.ssrc.value = ssrc;
  policy.ssrc.type = ssrc_specific;
  policy.window_size = filter->replay_window_size;
  policy.next = NULL;

  /* If it is the first stream, create the session
   * If not, add the stream policy to the session
   */
  if (filter->first_session)
    ret = srtp_create (&filter->session, &policy);
  else
    ret = srtp_add_stream (filter->session, &policy);

  if (stream->key)
    gst_buffer_unmap (stream->key, &map);

  if (ret == err_status_ok) {
    srtp_stream_t srtp_stream;

    srtp_stream = srtp_get_stream (filter->session, htonl (ssrc));
    if (srtp_stream) {
      /* Here, we just set the ROC, but we also need to set the initial
       * RTP sequence number later, otherwise libsrtp will not be able
       * to get the right packet index. */
      rdbx_set_roc (&srtp_stream->rtp_rdbx, stream->roc);
      filter->roc_changed = TRUE;
    }

    filter->first_session = FALSE;
    g_hash_table_insert (filter->streams, GUINT_TO_POINTER (stream->ssrc),
        stream);
  }

  return ret;
}
示例#6
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;
}
示例#7
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);
}