LCOV - code coverage report
Current view: top level - media/webrtc/signaling/src/mediapipeline - SrtpFlow.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 126 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       3             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : // Original author: ekr@rtfm.com
       6             : 
       7             : #include "logging.h"
       8             : #include "SrtpFlow.h"
       9             : 
      10             : #include "srtp.h"
      11             : #include "ssl.h"
      12             : #include "sslproto.h"
      13             : 
      14             : #include "mozilla/RefPtr.h"
      15             : 
      16             : // Logging context
      17             : using namespace mozilla;
      18           0 : MOZ_MTLOG_MODULE("mediapipeline")
      19             : 
      20             : namespace mozilla {
      21             : 
      22             : bool SrtpFlow::initialized;  // Static
      23             : 
      24           0 : SrtpFlow::~SrtpFlow() {
      25           0 :   if (session_) {
      26           0 :     srtp_dealloc(session_);
      27             :   }
      28           0 : }
      29             : 
      30           0 : RefPtr<SrtpFlow> SrtpFlow::Create(int cipher_suite,
      31             :                                            bool inbound,
      32             :                                            const void *key,
      33             :                                            size_t key_len) {
      34           0 :   nsresult res = Init();
      35           0 :   if (!NS_SUCCEEDED(res))
      36           0 :     return nullptr;
      37             : 
      38           0 :   RefPtr<SrtpFlow> flow = new SrtpFlow();
      39             : 
      40           0 :   if (!key) {
      41           0 :     MOZ_MTLOG(ML_ERROR, "Null SRTP key specified");
      42           0 :     return nullptr;
      43             :   }
      44             : 
      45           0 :   if (key_len != SRTP_TOTAL_KEY_LENGTH) {
      46           0 :     MOZ_MTLOG(ML_ERROR, "Invalid SRTP key length");
      47           0 :     return nullptr;
      48             :   }
      49             : 
      50             :   srtp_policy_t policy;
      51           0 :   memset(&policy, 0, sizeof(srtp_policy_t));
      52             : 
      53             :   // Note that we set the same cipher suite for RTP and RTCP
      54             :   // since any flow can only have one cipher suite with DTLS-SRTP
      55           0 :   switch (cipher_suite) {
      56             :     case SRTP_AES128_CM_HMAC_SHA1_80:
      57           0 :       MOZ_MTLOG(ML_DEBUG,
      58             :                 "Setting SRTP cipher suite SRTP_AES128_CM_HMAC_SHA1_80");
      59           0 :       crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
      60           0 :       crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
      61           0 :       break;
      62             :     case SRTP_AES128_CM_HMAC_SHA1_32:
      63           0 :       MOZ_MTLOG(ML_DEBUG,
      64             :                 "Setting SRTP cipher suite SRTP_AES128_CM_HMAC_SHA1_32");
      65           0 :       crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
      66           0 :       crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // 80-bit per RFC 5764
      67           0 :       break;                                                   // S 4.1.2.
      68             :     default:
      69           0 :       MOZ_MTLOG(ML_ERROR, "Request to set unknown SRTP cipher suite");
      70           0 :       return nullptr;
      71             :   }
      72             :   // This key is copied into the srtp_t object, so we don't
      73             :   // need to keep it.
      74           0 :   policy.key = const_cast<unsigned char *>(
      75             :       static_cast<const unsigned char *>(key));
      76           0 :   policy.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound;
      77           0 :   policy.ssrc.value = 0;
      78           0 :   policy.ekt = nullptr;
      79           0 :   policy.window_size = 1024;   // Use the Chrome value.  Needs to be revisited.  Default is 128
      80           0 :   policy.allow_repeat_tx = 1;  // Use Chrome value; needed for NACK mode to work
      81           0 :   policy.next = nullptr;
      82             : 
      83             :   // Now make the session
      84           0 :   err_status_t r = srtp_create(&flow->session_, &policy);
      85           0 :   if (r != err_status_ok) {
      86           0 :     MOZ_MTLOG(ML_ERROR, "Error creating srtp session");
      87           0 :     return nullptr;
      88             :   }
      89             : 
      90           0 :   return flow;
      91             : }
      92             : 
      93             : 
      94           0 : nsresult SrtpFlow::CheckInputs(bool protect, void *in, int in_len,
      95             :                                int max_len, int *out_len) {
      96           0 :   MOZ_ASSERT(in);
      97           0 :   if (!in) {
      98           0 :     MOZ_MTLOG(ML_ERROR, "NULL input value");
      99           0 :     return NS_ERROR_NULL_POINTER;
     100             :   }
     101             : 
     102           0 :   if (in_len < 0) {
     103           0 :     MOZ_MTLOG(ML_ERROR, "Input length is negative");
     104           0 :     return NS_ERROR_ILLEGAL_VALUE;
     105             :   }
     106             : 
     107           0 :   if (max_len < 0) {
     108           0 :     MOZ_MTLOG(ML_ERROR, "Max output length is negative");
     109           0 :     return NS_ERROR_ILLEGAL_VALUE;
     110             :   }
     111             : 
     112           0 :   if (protect) {
     113           0 :     if ((max_len < SRTP_MAX_EXPANSION) ||
     114           0 :         ((max_len - SRTP_MAX_EXPANSION) < in_len)) {
     115           0 :       MOZ_MTLOG(ML_ERROR, "Output too short");
     116           0 :       return NS_ERROR_ILLEGAL_VALUE;
     117             :     }
     118             :   }
     119             :   else {
     120           0 :     if (in_len > max_len) {
     121           0 :       MOZ_MTLOG(ML_ERROR, "Output too short");
     122           0 :       return NS_ERROR_ILLEGAL_VALUE;
     123             :     }
     124             :   }
     125             : 
     126           0 :   return NS_OK;
     127             : }
     128             : 
     129           0 : nsresult SrtpFlow::ProtectRtp(void *in, int in_len,
     130             :                               int max_len, int *out_len) {
     131           0 :   nsresult res = CheckInputs(true, in, in_len, max_len, out_len);
     132           0 :   if (NS_FAILED(res))
     133           0 :     return res;
     134             : 
     135           0 :   int len = in_len;
     136           0 :   err_status_t r = srtp_protect(session_, in, &len);
     137             : 
     138           0 :   if (r != err_status_ok) {
     139           0 :     MOZ_MTLOG(ML_ERROR, "Error protecting SRTP packet");
     140           0 :     return NS_ERROR_FAILURE;
     141             :   }
     142             : 
     143           0 :   MOZ_ASSERT(len <= max_len);
     144           0 :   *out_len = len;
     145             : 
     146             : 
     147           0 :   MOZ_MTLOG(ML_DEBUG, "Successfully protected an SRTP packet of len "
     148             :             << *out_len);
     149             : 
     150           0 :   return NS_OK;
     151             : }
     152             : 
     153           0 : nsresult SrtpFlow::UnprotectRtp(void *in, int in_len,
     154             :                                 int max_len, int *out_len) {
     155           0 :   nsresult res = CheckInputs(false, in, in_len, max_len, out_len);
     156           0 :   if (NS_FAILED(res))
     157           0 :     return res;
     158             : 
     159           0 :   int len = in_len;
     160           0 :   err_status_t r = srtp_unprotect(session_, in, &len);
     161             : 
     162           0 :   if (r != err_status_ok) {
     163           0 :     MOZ_MTLOG(ML_ERROR, "Error unprotecting SRTP packet error=" << (int)r);
     164           0 :     return NS_ERROR_FAILURE;
     165             :   }
     166             : 
     167           0 :   MOZ_ASSERT(len <= max_len);
     168           0 :   *out_len = len;
     169             : 
     170           0 :   MOZ_MTLOG(ML_DEBUG, "Successfully unprotected an SRTP packet of len "
     171             :             << *out_len);
     172             : 
     173           0 :   return NS_OK;
     174             : }
     175             : 
     176           0 : nsresult SrtpFlow::ProtectRtcp(void *in, int in_len,
     177             :                                int max_len, int *out_len) {
     178           0 :   nsresult res = CheckInputs(true, in, in_len, max_len, out_len);
     179           0 :   if (NS_FAILED(res))
     180           0 :     return res;
     181             : 
     182           0 :   int len = in_len;
     183           0 :   err_status_t r = srtp_protect_rtcp(session_, in, &len);
     184             : 
     185           0 :   if (r != err_status_ok) {
     186           0 :     MOZ_MTLOG(ML_ERROR, "Error protecting SRTCP packet");
     187           0 :     return NS_ERROR_FAILURE;
     188             :   }
     189             : 
     190           0 :   MOZ_ASSERT(len <= max_len);
     191           0 :   *out_len = len;
     192             : 
     193           0 :   MOZ_MTLOG(ML_DEBUG, "Successfully protected an SRTCP packet of len "
     194             :             << *out_len);
     195             : 
     196           0 :   return NS_OK;
     197             : }
     198             : 
     199           0 : nsresult SrtpFlow::UnprotectRtcp(void *in, int in_len,
     200             :                                  int max_len, int *out_len) {
     201           0 :   nsresult res = CheckInputs(false, in, in_len, max_len, out_len);
     202           0 :   if (NS_FAILED(res))
     203           0 :     return res;
     204             : 
     205           0 :   int len = in_len;
     206           0 :   err_status_t r = srtp_unprotect_rtcp(session_, in, &len);
     207             : 
     208           0 :   if (r != err_status_ok) {
     209           0 :     MOZ_MTLOG(ML_ERROR, "Error unprotecting SRTCP packet error=" << (int)r);
     210           0 :     return NS_ERROR_FAILURE;
     211             :   }
     212             : 
     213           0 :   MOZ_ASSERT(len <= max_len);
     214           0 :   *out_len = len;
     215             : 
     216           0 :   MOZ_MTLOG(ML_DEBUG, "Successfully unprotected an SRTCP packet of len "
     217             :             << *out_len);
     218             : 
     219           0 :   return NS_OK;
     220             : }
     221             : 
     222             : // Statics
     223           0 : void SrtpFlow::srtp_event_handler(srtp_event_data_t *data) {
     224             :   // TODO(ekr@rtfm.com): Implement this
     225           0 :   MOZ_CRASH();
     226             : }
     227             : 
     228           0 : nsresult SrtpFlow::Init() {
     229           0 :   if (!initialized) {
     230           0 :     err_status_t r = srtp_init();
     231           0 :     if (r != err_status_ok) {
     232           0 :       MOZ_MTLOG(ML_ERROR, "Could not initialize SRTP");
     233           0 :       MOZ_ASSERT(PR_FALSE);
     234             :       return NS_ERROR_FAILURE;
     235             :     }
     236             : 
     237           0 :     r = srtp_install_event_handler(&SrtpFlow::srtp_event_handler);
     238           0 :     if (r != err_status_ok) {
     239           0 :       MOZ_MTLOG(ML_ERROR, "Could not install SRTP event handler");
     240           0 :       MOZ_ASSERT(PR_FALSE);
     241             :       return NS_ERROR_FAILURE;
     242             :     }
     243             : 
     244           0 :     initialized = true;
     245             :   }
     246             : 
     247           0 :   return NS_OK;
     248             : }
     249             : 
     250             : }  // end of namespace
     251             : 

Generated by: LCOV version 1.13