Example #1
0
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;
}
Example #2
0
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;

}
Example #3
0
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;
}
Example #4
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;
}
Example #5
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;
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
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;
}
Example #11
0
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;
}
Example #12
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;
}
Example #13
0
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;
}
Example #14
0
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;  
}
Example #15
0
int main(int, char **)
{
    err_status_t status = srtp_init();
    return status == err_status_ok;
}
Example #16
0
/* 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;
}
Example #17
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;
}
Example #18
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;
}
Example #19
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, &params);

  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;
}
Example #20
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;
}
Example #21
0
err_status_t ortp_srtp_init(void)
{
	return srtp_init();
}
Example #22
0
err_status_t ortp_srtp_init(void)
{
	ortp_message("srtp init");
	return srtp_init();
}
Example #23
0
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;
}
Example #24
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);
}