Esempio n. 1
0
OpalRTPSession::SendReceiveStatus OpalDTLSSRTPSession::ExecuteHandshake(Channel channel)
{
  {
    PWaitAndSignal mutex(m_dataMutex);

    if (m_remotePort[channel] == 0)
      return e_IgnorePacket; // Too early

    if (m_sslChannel[channel] == NULL)
      return e_ProcessPacket; // Too late (done)
  }

  SSLChannel & sslChannel = *m_sslChannel[channel];
  if (!sslChannel.ExecuteHandshake())
    return e_AbortTransport;

  const OpalMediaCryptoSuite* cryptoSuite = NULL;
  srtp_profile_t profile = srtp_profile_reserved;
  for (PINDEX i = 0; i < PARRAYSIZE(ProfileNames); ++i) {
    if (sslChannel.GetSelectedProfile() == ProfileNames[i].m_dtlsName) {
      profile = ProfileNames[i].m_profile;
      cryptoSuite = OpalMediaCryptoSuiteFactory::CreateInstance(ProfileNames[i].m_opalName);
      break;
    }
  }

  if (profile == srtp_profile_reserved || cryptoSuite == NULL) {
    PTRACE(2, "Error in SRTP profile.");
    return e_AbortTransport;
  }

  PINDEX masterKeyLength = srtp_profile_get_master_key_length(profile);
  PINDEX masterSaltLength = srtp_profile_get_master_salt_length(profile);

  PBYTEArray keyMaterial = sslChannel.GetKeyMaterial(((masterSaltLength + masterKeyLength) << 1), "EXTRACTOR-dtls_srtp");
  if (keyMaterial.IsEmpty())
    return e_AbortTransport;

  OpalSRTPKeyInfo * keyInfo = dynamic_cast<OpalSRTPKeyInfo*>(cryptoSuite->CreateKeyInfo());
  PAssertNULL(keyInfo);

  keyInfo->SetCipherKey(PBYTEArray(keyMaterial, masterKeyLength));
  keyInfo->SetAuthSalt(PBYTEArray(keyMaterial + masterKeyLength*2, masterSaltLength));
  ApplyKeyToSRTP(*keyInfo, sslChannel.IsServer() ? e_Receiver : e_Sender);

  keyInfo->SetCipherKey(PBYTEArray(keyMaterial + masterKeyLength, masterKeyLength));
  keyInfo->SetAuthSalt(PBYTEArray(keyMaterial + masterKeyLength*2 + masterSaltLength, masterSaltLength));
  ApplyKeyToSRTP(*keyInfo, sslChannel.IsServer() ? e_Sender : e_Receiver);

  delete keyInfo;

  m_queueChannel[channel].Close();
  sslChannel.Detach(PChannel::ShutdownWrite); // Do not close the socket!
  delete m_sslChannel[channel];
  m_sslChannel[channel] = NULL;
  return e_ProcessPacket;
}
Esempio n. 2
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;
}