10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* 20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle 30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2009 Google Inc. 40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer. 100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * and/or other materials provided with the distribution. 130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * derived from this software without specific prior written permission. 150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */ 270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#undef HAVE_CONFIG_H 290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/session/media/srtpfilter.h" 310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 32b9518277716cf5081d3058d86ab7d98b78f696e8pbos@webrtc.org#include <string.h> 33b9518277716cf5081d3058d86ab7d98b78f696e8pbos@webrtc.org 340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <algorithm> 350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 36cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/base/rtputils.h" 372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/base64.h" 382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/logging.h" 392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/stringencode.h" 402a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/timeutils.h" 410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Enable this line to turn on SRTP debugging 430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// #define SRTP_DEBUG 440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef HAVE_SRTP 460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef SRTP_RELATIVE_PATH 470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "srtp.h" // NOLINT 48e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.orgextern "C" srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc); 49e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#include "srtp_priv.h" // NOLINT 500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#else 510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "third_party/libsrtp/include/srtp.h" 52e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.orgextern "C" srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc); 53e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#include "third_party/libsrtp/include/srtp_priv.h" 540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // SRTP_RELATIVE_PATH 55e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#ifdef ENABLE_EXTERNAL_AUTH 5678afd903598b85bd36e67ca5a4cf8e631cef6eaehenrike@webrtc.org#include "talk/session/media/externalhmac.h" 57e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#endif // ENABLE_EXTERNAL_AUTH 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef _DEBUG 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgextern "C" debug_module_t mod_srtp; 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgextern "C" debug_module_t mod_auth; 610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgextern "C" debug_module_t mod_cipher; 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgextern "C" debug_module_t mod_stat; 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgextern "C" debug_module_t mod_alloc; 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgextern "C" debug_module_t mod_aes_icm; 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgextern "C" debug_module_t mod_aes_hmac; 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#else 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// SrtpFilter needs that constant. 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define SRTP_MASTER_KEY_LEN 30 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // HAVE_SRTP 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace cricket { 730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char CS_AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80"; 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char CS_AES_CM_128_HMAC_SHA1_32[] = "AES_CM_128_HMAC_SHA1_32"; 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int SRTP_MASTER_KEY_BASE64_LEN = SRTP_MASTER_KEY_LEN * 4 / 3; 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int SRTP_MASTER_KEY_KEY_LEN = 16; 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int SRTP_MASTER_KEY_SALT_LEN = 14; 790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifndef HAVE_SRTP 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// This helper function is used on systems that don't (yet) have SRTP, 830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// to log that the functions that require it won't do anything. 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace { 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpNotAvailable(const char *func) { 860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << func << ": SRTP is not available on your system."; 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // anonymous namespace 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // !HAVE_SRTP 920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid EnableSrtpDebugging() { 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef HAVE_SRTP 950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef _DEBUG 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org debug_on(mod_srtp); 970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org debug_on(mod_auth); 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org debug_on(mod_cipher); 990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org debug_on(mod_stat); 1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org debug_on(mod_alloc); 1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org debug_on(mod_aes_icm); 1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // debug_on(mod_aes_cbc); 1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // debug_on(mod_hmac); 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif 1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // HAVE_SRTP 1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 108f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org// NOTE: This is called from ChannelManager D'tor. 109f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.orgvoid ShutdownSrtp() { 110f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org#ifdef HAVE_SRTP 111f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // If srtp_dealloc is not executed then this will clear all existing sessions. 112f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // This should be called when application is shutting down. 113f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org SrtpSession::Terminate(); 114f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org#endif 115f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org} 116f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSrtpFilter::SrtpFilter() 1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : state_(ST_INIT), 1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signal_silent_time_in_ms_(0) { 1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSrtpFilter::~SrtpFilter() { 1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::IsActive() const { 1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return state_ >= ST_ACTIVE; 1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::SetOffer(const std::vector<CryptoParams>& offer_params, 1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ContentSource source) { 1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ExpectOffer(source)) { 1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Wrong state to update SRTP offer"; 1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return StoreParams(offer_params, source); 1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::SetAnswer(const std::vector<CryptoParams>& answer_params, 1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ContentSource source) { 1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return DoSetAnswer(answer_params, source, true); 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::SetProvisionalAnswer( 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::vector<CryptoParams>& answer_params, 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ContentSource source) { 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return DoSetAnswer(answer_params, source, false); 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::SetRtpParams(const std::string& send_cs, 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const uint8* send_key, int send_key_len, 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& recv_cs, 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const uint8* recv_key, int recv_key_len) { 1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (state_ == ST_ACTIVE) { 1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active"; 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CreateSrtpSessions(); 1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!send_session_->SetSend(send_cs, send_key, send_key_len)) 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) 1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = ST_ACTIVE; 1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SRTP activated with negotiated parameters:" 1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " send cipher_suite " << send_cs 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " recv cipher_suite " << recv_cs; 1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// This function is provided separately because DTLS-SRTP behaves 1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// differently in RTP/RTCP mux and non-mux modes. 1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// - In the non-muxed case, RTP and RTCP are keyed with different 1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// keys (from different DTLS handshakes), and so we need a new 1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// SrtpSession. 1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// - In the muxed case, they are keyed with the same keys, so 1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// this function is not needed 1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::SetRtcpParams(const std::string& send_cs, 1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const uint8* send_key, int send_key_len, 1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& recv_cs, 1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const uint8* recv_key, int recv_key_len) { 1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This can only be called once, but can be safely called after 1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // SetRtpParams 1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (send_rtcp_session_ || recv_rtcp_session_) { 1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; 1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_rtcp_session_.reset(new SrtpSession()); 1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError); 1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); 1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) 1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org recv_rtcp_session_.reset(new SrtpSession()); 1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError); 1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); 2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) 2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SRTCP activated with negotiated parameters:" 2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " send cipher_suite " << send_cs 2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " recv cipher_suite " << recv_cs; 2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { 2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!IsActive()) { 2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; 2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return send_session_->ProtectRtp(p, in_len, max_len, out_len); 2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 218e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.orgbool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len, 219e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org int64* index) { 220e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org if (!IsActive()) { 221e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; 222e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return false; 223e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org } 224e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 225e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return send_session_->ProtectRtp(p, in_len, max_len, out_len, index); 226e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org} 227e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { 2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!IsActive()) { 2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active"; 2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (send_rtcp_session_) { 2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len); 2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return send_session_->ProtectRtcp(p, in_len, max_len, out_len); 2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) { 2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!IsActive()) { 2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active"; 2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return recv_session_->UnprotectRtp(p, in_len, out_len); 2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) { 2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!IsActive()) { 2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active"; 2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (recv_rtcp_session_) { 2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len); 2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return recv_session_->UnprotectRtcp(p, in_len, out_len); 2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 260e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.orgbool SrtpFilter::GetRtpAuthParams(uint8** key, int* key_len, int* tag_len) { 261e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org if (!IsActive()) { 262e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org LOG(LS_WARNING) << "Failed to GetRtpAuthParams: SRTP not active"; 263e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return false; 264e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org } 265e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 266e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return send_session_->GetRtpAuthParams(key, key_len, tag_len); 267e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org} 268e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpFilter::set_signal_silent_time(uint32 signal_silent_time_in_ms) { 2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signal_silent_time_in_ms_ = signal_silent_time_in_ms; 2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (state_ == ST_ACTIVE) { 2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_session_->set_signal_silent_time(signal_silent_time_in_ms); 2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org recv_session_->set_signal_silent_time(signal_silent_time_in_ms); 2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (send_rtcp_session_) 2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); 2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (recv_rtcp_session_) 2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); 2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::ExpectOffer(ContentSource source) { 2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ((state_ == ST_INIT) || 2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_ACTIVE) || 2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_SENTOFFER && source == CS_LOCAL) || 2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || 2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || 2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); 2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, 2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ContentSource source) { 2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org offer_params_ = params; 2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (state_ == ST_INIT) { 2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER; 2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { // state >= ST_ACTIVE 2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = 2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (source == CS_LOCAL) ? ST_SENTUPDATEDOFFER : ST_RECEIVEDUPDATEDOFFER; 2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::ExpectAnswer(ContentSource source) { 3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ((state_ == ST_SENTOFFER && source == CS_REMOTE) || 3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL) || 3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_SENTUPDATEDOFFER && source == CS_REMOTE) || 3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_LOCAL) || 3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_SENTPRANSWER_NO_CRYPTO && source == CS_LOCAL) || 3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_SENTPRANSWER && source == CS_LOCAL) || 3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_RECEIVEDPRANSWER_NO_CRYPTO && source == CS_REMOTE) || 3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (state_ == ST_RECEIVEDPRANSWER && source == CS_REMOTE)); 3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::DoSetAnswer(const std::vector<CryptoParams>& answer_params, 3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ContentSource source, 3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool final) { 3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ExpectAnswer(source)) { 3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Invalid state for SRTP answer"; 3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If the answer doesn't requests crypto complete the negotiation of an 3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // unencrypted session. 3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Otherwise, finalize the parameters and apply them. 3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (answer_params.empty()) { 3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (final) { 3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ResetParams(); 3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Need to wait for the final answer to decide if 3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // we should go to Active state. 3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO : 3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ST_RECEIVEDPRANSWER_NO_CRYPTO; 3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CryptoParams selected_params; 3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!NegotiateParams(answer_params, &selected_params)) 3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const CryptoParams& send_params = 3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (source == CS_REMOTE) ? selected_params : answer_params[0]; 3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const CryptoParams& recv_params = 3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (source == CS_REMOTE) ? answer_params[0] : selected_params; 3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ApplyParams(send_params, recv_params)) { 3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (final) { 3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org offer_params_.clear(); 3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = ST_ACTIVE; 3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = 3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER; 3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpFilter::CreateSrtpSessions() { 3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_session_.reset(new SrtpSession()); 3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org applied_send_params_ = CryptoParams(); 3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org recv_session_.reset(new SrtpSession()); 3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org applied_recv_params_ = CryptoParams(); 3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalSrtpError.repeat(send_session_->SignalSrtpError); 3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalSrtpError.repeat(recv_session_->SignalSrtpError); 3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_session_->set_signal_silent_time(signal_silent_time_in_ms_); 3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org recv_session_->set_signal_silent_time(signal_silent_time_in_ms_); 3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, 3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CryptoParams* selected_params) { 3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We're processing an accept. We should have exactly one set of params, 3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // unless the offer didn't mention crypto, in which case we shouldn't be here. 3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool ret = (answer_params.size() == 1U && !offer_params_.empty()); 3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ret) { 3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We should find a match between the answer params and the offered params. 3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<CryptoParams>::const_iterator it; 3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (it = offer_params_.begin(); it != offer_params_.end(); ++it) { 3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (answer_params[0].Matches(*it)) { 3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (it != offer_params_.end()) { 3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *selected_params = *it; 3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = false; 3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ret) { 3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Invalid parameters in SRTP answer"; 3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ret; 3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::ApplyParams(const CryptoParams& send_params, 3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const CryptoParams& recv_params) { 3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(jiayl): Split this method to apply send and receive CryptoParams 3990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // independently, so that we can skip one method when either send or receive 4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // CryptoParams is unchanged. 4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (applied_send_params_.cipher_suite == send_params.cipher_suite && 4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org applied_send_params_.key_params == send_params.key_params && 4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org applied_recv_params_.cipher_suite == recv_params.cipher_suite && 4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org applied_recv_params_.key_params == recv_params.key_params) { 4050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op."; 4060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We do not want to reset the ROC if the keys are the same. So just return. 4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(juberti): Zero these buffers after use. 4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool ret; 4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint8 send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN]; 4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) && 4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ParseKeyParams(recv_params.key_params, recv_key, sizeof(recv_key))); 4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ret) { 4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CreateSrtpSessions(); 4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = (send_session_->SetSend(send_params.cipher_suite, 4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_key, sizeof(send_key)) && 4190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org recv_session_->SetRecv(recv_params.cipher_suite, 4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org recv_key, sizeof(recv_key))); 4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ret) { 4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SRTP activated with negotiated parameters:" 4240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " send cipher_suite " << send_params.cipher_suite 4250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " recv cipher_suite " << recv_params.cipher_suite; 4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org applied_send_params_ = send_params; 4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org applied_recv_params_ = recv_params; 4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; 4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ret; 4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::ResetParams() { 4350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org offer_params_.clear(); 4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = ST_INIT; 4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SRTP reset to init state"; 4380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpFilter::ParseKeyParams(const std::string& key_params, 4420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint8* key, int len) { 4430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" 4440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Fail if key-method is wrong. 4460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (key_params.find("inline:") != 0) { 4470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 4480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Fail if base64 decode fails, or the key is the wrong size. 4510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string key_b64(key_params.substr(7)), key_str; 4522a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, 4530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &key_str, NULL) || 4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org static_cast<int>(key_str.size()) != len) { 4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org memcpy(key, key_str.c_str(), len); 4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 4600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 4630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// SrtpSession 4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef HAVE_SRTP 4660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::inited_ = false; 4680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSrtpSession::SrtpSession() 4700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : session_(NULL), 4710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rtp_auth_tag_len_(0), 4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rtcp_auth_tag_len_(0), 4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org srtp_stat_(new SrtpStat()), 4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org last_send_seq_num_(-1) { 4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sessions()->push_back(this); 4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalSrtpError.repeat(srtp_stat_->SignalSrtpError); 4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSrtpSession::~SrtpSession() { 4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sessions()->erase(std::find(sessions()->begin(), sessions()->end(), this)); 4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (session_) { 4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org srtp_dealloc(session_); 4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) { 4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SetKey(ssrc_any_outbound, cs, key, len); 4880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) { 4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SetKey(ssrc_any_inbound, cs, key, len); 4920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { 4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!session_) { 4960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; 4970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 4980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int need_len = in_len + rtp_auth_tag_len_; // NOLINT 5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (max_len < need_len) { 5020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " 5030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << max_len << " is less than the needed " << need_len; 5040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *out_len = in_len; 5080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int err = srtp_protect(session_, p, out_len); 5090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc; 5100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (GetRtpSsrc(p, in_len, &ssrc)) { 5110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org srtp_stat_->AddProtectRtpResult(ssrc, err); 5120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int seq_num; 5140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org GetRtpSeqNum(p, in_len, &seq_num); 5150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (err != err_status_ok) { 5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTP packet, seqnum=" 5170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << seq_num << ", err=" << err << ", last seqnum=" 5180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << last_send_seq_num_; 5190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org last_send_seq_num_ = seq_num; 5220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 5230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 525e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.orgbool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len, 526e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org int64* index) { 527e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org if (!ProtectRtp(p, in_len, max_len, out_len)) { 528e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return false; 529e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org } 530e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return (index) ? GetSendStreamPacketIndex(p, in_len, index) : true; 531e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org} 532e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 5330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { 5340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!session_) { 5350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session"; 5360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int need_len = in_len + sizeof(uint32) + rtcp_auth_tag_len_; // NOLINT 5400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (max_len < need_len) { 5410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length " 5420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << max_len << " is less than the needed " << need_len; 5430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *out_len = in_len; 5470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int err = srtp_protect_rtcp(session_, p, out_len); 5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org srtp_stat_->AddProtectRtcpResult(err); 5490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (err != err_status_ok) { 5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; 5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 5540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { 5570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!session_) { 5580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session"; 5590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *out_len = in_len; 5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int err = srtp_unprotect(session_, p, out_len); 5640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc; 5650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (GetRtpSsrc(p, in_len, &ssrc)) { 5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org srtp_stat_->AddUnprotectRtpResult(ssrc, err); 5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (err != err_status_ok) { 5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; 5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 5730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { 5760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!session_) { 5770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session"; 5780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *out_len = in_len; 5820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int err = srtp_unprotect_rtcp(session_, p, out_len); 5830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org srtp_stat_->AddUnprotectRtcpResult(err); 5840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (err != err_status_ok) { 5850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; 5860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 5890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 591e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.orgbool SrtpSession::GetRtpAuthParams(uint8** key, int* key_len, 592e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org int* tag_len) { 593e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#if defined(ENABLE_EXTERNAL_AUTH) 594e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org external_hmac_ctx_t* external_hmac = NULL; 595e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // stream_template will be the reference context for other streams. 596e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // Let's use it for getting the keys. 597e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org srtp_stream_ctx_t* srtp_context = session_->stream_template; 598e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org if (srtp_context && srtp_context->rtp_auth) { 599e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org external_hmac = reinterpret_cast<external_hmac_ctx_t*>( 600e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org srtp_context->rtp_auth->state); 601e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org } 602e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 603e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org if (!external_hmac) { 604e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org LOG(LS_ERROR) << "Failed to get auth keys from libsrtp!."; 605e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return false; 606e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org } 607e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 608e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org *key = external_hmac->key; 609e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org *key_len = external_hmac->key_length; 610e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org *tag_len = rtp_auth_tag_len_; 611e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return true; 612e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#else 613e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return false; 614e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#endif 615e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org} 616e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 617e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.orgbool SrtpSession::GetSendStreamPacketIndex(void* p, int in_len, int64* index) { 618e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org srtp_hdr_t* hdr = reinterpret_cast<srtp_hdr_t*>(p); 619e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org srtp_stream_ctx_t* stream = srtp_get_stream(session_, hdr->ssrc); 620e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org if (stream == NULL) 621e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return false; 622e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 623b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org // Shift packet index, put into network byte order 624b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org *index = be64_to_cpu(rdbx_get_packet_index(&stream->rtp_rdbx) << 16); 625e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return true; 626e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org} 627e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 6280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpSession::set_signal_silent_time(uint32 signal_silent_time_in_ms) { 6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); 6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::SetKey(int type, const std::string& cs, 6330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const uint8* key, int len) { 6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (session_) { 6350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Failed to create SRTP session: " 6360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << "SRTP session already created"; 6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 6380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!Init()) { 6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 6420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org srtp_policy_t policy; 6450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org memset(&policy, 0, sizeof(policy)); 6460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (cs == CS_AES_CM_128_HMAC_SHA1_80) { 6480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); 6490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); 6500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (cs == CS_AES_CM_128_HMAC_SHA1_32) { 6510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32, 6520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80 6530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 6540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" 6550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " cipher_suite " << cs.c_str(); 6560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 6570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!key || len != SRTP_MASTER_KEY_LEN) { 6600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to create SRTP session: invalid key"; 6610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 6620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org policy.ssrc.type = static_cast<ssrc_type_t>(type); 6650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org policy.ssrc.value = 0; 6660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org policy.key = const_cast<uint8*>(key); 6670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(astor) parse window size from WSH session-param 6680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org policy.window_size = 1024; 6690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org policy.allow_repeat_tx = 1; 670e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // If external authentication option is enabled, supply custom auth module 671e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // id EXTERNAL_HMAC_SHA1 in the policy structure. 672e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // We want to set this option only for rtp packets. 673e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // By default policy structure is initialized to HMAC_SHA1. 674e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#if defined(ENABLE_EXTERNAL_AUTH) 675b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org // Enable external HMAC authentication only for outgoing streams. 676b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org if (type == ssrc_any_outbound) { 677b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org policy.rtp.auth_type = EXTERNAL_HMAC_SHA1; 678b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org } 679e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#endif 6800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org policy.next = NULL; 6810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int err = srtp_create(&session_, &policy); 6830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (err != err_status_ok) { 6840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; 6850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 6860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 688e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 6890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rtp_auth_tag_len_ = policy.rtp.auth_tag_len; 6900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; 6910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 6920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::Init() { 6950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!inited_) { 6960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int err; 6970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org err = srtp_init(); 6980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (err != err_status_ok) { 6990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Failed to init SRTP, err=" << err; 7000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 7010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org err = srtp_install_event_handler(&SrtpSession::HandleEventThunk); 7040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (err != err_status_ok) { 7050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err; 7060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 7070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 708e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#if defined(ENABLE_EXTERNAL_AUTH) 709e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org err = external_crypto_init(); 710e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org if (err != err_status_ok) { 711e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err; 712e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org return false; 713e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org } 714e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org#endif 7150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org inited_ = true; 7160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 7190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 721f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.orgvoid SrtpSession::Terminate() { 722f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (inited_) { 723f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int err = srtp_shutdown(); 724f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (err) { 725f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err; 726f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return; 727f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 728f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org inited_ = false; 729f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 730f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org} 731f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 7320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpSession::HandleEvent(const srtp_event_data_t* ev) { 7330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (ev->event) { 7340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case event_ssrc_collision: 7350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: SSRC collision"; 7360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 7370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case event_key_soft_limit: 7380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: reached soft key usage limit"; 7390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 7400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case event_key_hard_limit: 7410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: reached hard key usage limit"; 7420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 7430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case event_packet_index_limit: 7440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)"; 7450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 7460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org default: 7470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: unknown " << ev->event; 7480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 7490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { 7530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::list<SrtpSession*>::iterator it = sessions()->begin(); 7540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != sessions()->end(); ++it) { 7550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((*it)->session_ == ev->session) { 7560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (*it)->HandleEvent(ev); 7570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 7580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstd::list<SrtpSession*>* SrtpSession::sessions() { 7630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LIBJINGLE_DEFINE_STATIC_LOCAL(std::list<SrtpSession*>, sessions, ()); 7640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return &sessions; 7650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#else // !HAVE_SRTP 7680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// On some systems, SRTP is not (yet) available. 7700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSrtpSession::SrtpSession() { 7720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(WARNING) << "SRTP implementation is missing."; 7730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSrtpSession::~SrtpSession() { 7760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) { 7790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 7800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) { 7830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 7840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::ProtectRtp(void* data, int in_len, int max_len, 7870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int* out_len) { 7880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 7890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::ProtectRtcp(void* data, int in_len, int max_len, 7920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int* out_len) { 7930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 7940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::UnprotectRtp(void* data, int in_len, int* out_len) { 7970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 7980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool SrtpSession::UnprotectRtcp(void* data, int in_len, int* out_len) { 8010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 8020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpSession::set_signal_silent_time(uint32 signal_silent_time) { 8050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Do nothing. 8060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // HAVE_SRTP 8090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 8110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// SrtpStat 8120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef HAVE_SRTP 8140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSrtpStat::SrtpStat() 8160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : signal_silent_time_(1000) { 8170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::AddProtectRtpResult(uint32 ssrc, int result) { 8200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org FailureKey key; 8210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.ssrc = ssrc; 8220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.mode = SrtpFilter::PROTECT; 8230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (result) { 8240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case err_status_ok: 8250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.error = SrtpFilter::ERROR_NONE; 8260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 8270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case err_status_auth_fail: 8280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.error = SrtpFilter::ERROR_AUTH; 8290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 8300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org default: 8310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.error = SrtpFilter::ERROR_FAIL; 8320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org HandleSrtpResult(key); 8340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::AddUnprotectRtpResult(uint32 ssrc, int result) { 8370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org FailureKey key; 8380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.ssrc = ssrc; 8390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.mode = SrtpFilter::UNPROTECT; 8400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (result) { 8410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case err_status_ok: 8420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.error = SrtpFilter::ERROR_NONE; 8430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 8440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case err_status_auth_fail: 8450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.error = SrtpFilter::ERROR_AUTH; 8460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 8470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case err_status_replay_fail: 8480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case err_status_replay_old: 8490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.error = SrtpFilter::ERROR_REPLAY; 8500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 8510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org default: 8520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org key.error = SrtpFilter::ERROR_FAIL; 8530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org HandleSrtpResult(key); 8550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::AddProtectRtcpResult(int result) { 8580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AddProtectRtpResult(0U, result); 8590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::AddUnprotectRtcpResult(int result) { 8620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AddUnprotectRtpResult(0U, result); 8630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { 8660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Handle some cases where error should be signalled right away. For other 8670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // errors, trigger error for the first time seeing it. After that, silent 8680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // the same error for a certain amount of time (default 1 sec). 8690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (key.error != SrtpFilter::ERROR_NONE) { 8700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // For errors, signal first time and wait for 1 sec. 8710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org FailureStat* stat = &(failures_[key]); 8722a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org uint32 current_time = rtc::Time(); 8730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (stat->last_signal_time == 0 || 8742a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::TimeDiff(current_time, stat->last_signal_time) > 8750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org static_cast<int>(signal_silent_time_)) { 8760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalSrtpError(key.ssrc, key.mode, key.error); 8770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stat->last_signal_time = current_time; 8780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#else // !HAVE_SRTP 8830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// On some systems, SRTP is not (yet) available. 8850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSrtpStat::SrtpStat() 8870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : signal_silent_time_(1000) { 8880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(WARNING) << "SRTP implementation is missing."; 8890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::AddProtectRtpResult(uint32 ssrc, int result) { 8920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 8930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::AddUnprotectRtpResult(uint32 ssrc, int result) { 8960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 8970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::AddProtectRtcpResult(int result) { 9000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 9010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::AddUnprotectRtcpResult(int result) { 9040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 9050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { 9080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 9090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // HAVE_SRTP 9120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace cricket 914