128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/* 228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * libjingle 328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Copyright 2009 Google Inc. 428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * this list of conditions and the following disclaimer. 1028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 1128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 1228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * and/or other materials provided with the distribution. 1328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 1428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * derived from this software without specific prior written permission. 1528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 1628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 1728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 1928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 2728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#undef HAVE_CONFIG_H 2928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "talk/session/media/srtpfilter.h" 3128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 32371243dfa3467c7be7217da4b537cc33d2bd45a6pbos@webrtc.org#include <string.h> 33371243dfa3467c7be7217da4b537cc33d2bd45a6pbos@webrtc.org 3428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <algorithm> 3528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 36a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "talk/media/base/rtputils.h" 37d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/base64.h" 384b3c0d6f34c379c2a06f654b62403876b20180c6Jiayang Liu#include "webrtc/base/byteorder.h" 399478437fdea4eb31b92ffe0c10368fe5bc9b9e16Karl Wiberg#include "webrtc/base/common.h" 40d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/logging.h" 41d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/stringencode.h" 42d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/timeutils.h" 4328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Enable this line to turn on SRTP debugging 4528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// #define SRTP_DEBUG 4628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifdef HAVE_SRTP 48a197a5eed68ad29e42cde83052abdc55efbcd65fjiayl@webrtc.orgextern "C" { 4928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifdef SRTP_RELATIVE_PATH 5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "srtp.h" // NOLINT 51a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#include "srtp_priv.h" // NOLINT 5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#else 53a197a5eed68ad29e42cde83052abdc55efbcd65fjiayl@webrtc.org#include "third_party/libsrtp/srtp/include/srtp.h" 54a197a5eed68ad29e42cde83052abdc55efbcd65fjiayl@webrtc.org#include "third_party/libsrtp/srtp/include/srtp_priv.h" 5528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif // SRTP_RELATIVE_PATH 56a197a5eed68ad29e42cde83052abdc55efbcd65fjiayl@webrtc.org} 57a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#ifdef ENABLE_EXTERNAL_AUTH 58d43aa9de7a4a2b793e5ec59c86fb0b81e4052bb0henrike@webrtc.org#include "talk/session/media/externalhmac.h" 59a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#endif // ENABLE_EXTERNAL_AUTH 60ff134ebd3d35ae2edd6eaa63b0a19cb16cc256b7tfarina#if !defined(NDEBUG) 6128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgextern "C" debug_module_t mod_srtp; 6228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgextern "C" debug_module_t mod_auth; 6328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgextern "C" debug_module_t mod_cipher; 6428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgextern "C" debug_module_t mod_stat; 6528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgextern "C" debug_module_t mod_alloc; 6628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgextern "C" debug_module_t mod_aes_icm; 6728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgextern "C" debug_module_t mod_aes_hmac; 6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif 6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#else 7028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// SrtpFilter needs that constant. 7128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#define SRTP_MASTER_KEY_LEN 30 7228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif // HAVE_SRTP 7328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgnamespace cricket { 7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgconst int SRTP_MASTER_KEY_BASE64_LEN = SRTP_MASTER_KEY_LEN * 4 / 3; 7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgconst int SRTP_MASTER_KEY_KEY_LEN = 16; 7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgconst int SRTP_MASTER_KEY_SALT_LEN = 14; 7928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifndef HAVE_SRTP 8128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// This helper function is used on systems that don't (yet) have SRTP, 8328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// to log that the functions that require it won't do anything. 8428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgnamespace { 8528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpNotAvailable(const char *func) { 8628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << func << ": SRTP is not available on your system."; 8728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 8828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 8928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} // anonymous namespace 9028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif // !HAVE_SRTP 9228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid EnableSrtpDebugging() { 9428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifdef HAVE_SRTP 95ff134ebd3d35ae2edd6eaa63b0a19cb16cc256b7tfarina#if !defined(NDEBUG) 9628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org debug_on(mod_srtp); 9728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org debug_on(mod_auth); 9828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org debug_on(mod_cipher); 9928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org debug_on(mod_stat); 10028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org debug_on(mod_alloc); 10128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org debug_on(mod_aes_icm); 10228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // debug_on(mod_aes_cbc); 10328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // debug_on(mod_hmac); 10428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif 10528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif // HAVE_SRTP 10628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 10728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 1089dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org// NOTE: This is called from ChannelManager D'tor. 1099dba52562725dbaced0d671982201ede753d72e8wu@webrtc.orgvoid ShutdownSrtp() { 1109dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org#ifdef HAVE_SRTP 1119dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org // If srtp_dealloc is not executed then this will clear all existing sessions. 1129dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org // This should be called when application is shutting down. 1139dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org SrtpSession::Terminate(); 1149dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org#endif 1159dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org} 1169dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org 11728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgSrtpFilter::SrtpFilter() 11828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : state_(ST_INIT), 11928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org signal_silent_time_in_ms_(0) { 12028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 12128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 12228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgSrtpFilter::~SrtpFilter() { 12328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 12428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 12528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::IsActive() const { 12628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return state_ >= ST_ACTIVE; 12728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 12828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 12928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::SetOffer(const std::vector<CryptoParams>& offer_params, 13028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ContentSource source) { 13128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!ExpectOffer(source)) { 13228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Wrong state to update SRTP offer"; 13328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 13428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 13528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return StoreParams(offer_params, source); 13628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 13728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 13828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::SetAnswer(const std::vector<CryptoParams>& answer_params, 13928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ContentSource source) { 14028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return DoSetAnswer(answer_params, source, true); 14128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 14228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 14328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::SetProvisionalAnswer( 14428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const std::vector<CryptoParams>& answer_params, 14528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ContentSource source) { 14628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return DoSetAnswer(answer_params, source, false); 14728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 14828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 149521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shiehbool SrtpFilter::SetRtpParams(int send_cs, 1500c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström const uint8_t* send_key, 1510c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int send_key_len, 152521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh int recv_cs, 1530c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström const uint8_t* recv_key, 1540c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int recv_key_len) { 1552e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org if (IsActive()) { 15628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active"; 15728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 15828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 15928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org CreateSrtpSessions(); 16028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!send_session_->SetSend(send_cs, send_key, send_key_len)) 16128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 16228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 16328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) 16428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 16528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 16628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org state_ = ST_ACTIVE; 16728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 16828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "SRTP activated with negotiated parameters:" 16928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << " send cipher_suite " << send_cs 17028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << " recv cipher_suite " << recv_cs; 17128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 17228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 17328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 17428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// This function is provided separately because DTLS-SRTP behaves 17528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// differently in RTP/RTCP mux and non-mux modes. 17628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// 17728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// - In the non-muxed case, RTP and RTCP are keyed with different 17828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// keys (from different DTLS handshakes), and so we need a new 17928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// SrtpSession. 18028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// - In the muxed case, they are keyed with the same keys, so 18128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// this function is not needed 182521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shiehbool SrtpFilter::SetRtcpParams(int send_cs, 1830c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström const uint8_t* send_key, 1840c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int send_key_len, 185521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh int recv_cs, 1860c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström const uint8_t* recv_key, 1870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int recv_key_len) { 18828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // This can only be called once, but can be safely called after 18928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // SetRtpParams 19028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (send_rtcp_session_ || recv_rtcp_session_) { 19128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; 19228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 19328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 19428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 19528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org send_rtcp_session_.reset(new SrtpSession()); 19628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError); 19728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); 19828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) 19928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 20028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 20128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org recv_rtcp_session_.reset(new SrtpSession()); 20228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError); 20328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); 20428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) 20528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 20628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 20728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "SRTCP activated with negotiated parameters:" 20828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << " send cipher_suite " << send_cs 20928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << " recv cipher_suite " << recv_cs; 21028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 21128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 21228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 21328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 21428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { 21528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!IsActive()) { 21628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; 21728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 21828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 2192e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org ASSERT(send_session_ != NULL); 22028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return send_session_->ProtectRtp(p, in_len, max_len, out_len); 22128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 22228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2230c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool SrtpFilter::ProtectRtp(void* p, 2240c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int in_len, 2250c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int max_len, 2260c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int* out_len, 2270c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int64_t* index) { 228a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org if (!IsActive()) { 229a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; 230a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return false; 231a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org } 2322e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org ASSERT(send_session_ != NULL); 233a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return send_session_->ProtectRtp(p, in_len, max_len, out_len, index); 234a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org} 235a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org 23628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { 23728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!IsActive()) { 23828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active"; 23928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 24028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 24128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (send_rtcp_session_) { 24228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len); 24328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 2442e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org ASSERT(send_session_ != NULL); 24528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return send_session_->ProtectRtcp(p, in_len, max_len, out_len); 24628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 24728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 24828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 24928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) { 25028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!IsActive()) { 25128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active"; 25228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 25328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 2542e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org ASSERT(recv_session_ != NULL); 25528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return recv_session_->UnprotectRtp(p, in_len, out_len); 25628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 25728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 25828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) { 25928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!IsActive()) { 26028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active"; 26128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 26228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 26328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (recv_rtcp_session_) { 26428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len); 26528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 2662e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org ASSERT(recv_session_ != NULL); 26728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return recv_session_->UnprotectRtcp(p, in_len, out_len); 26828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 26928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 27028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2710c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool SrtpFilter::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { 272a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org if (!IsActive()) { 273a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org LOG(LS_WARNING) << "Failed to GetRtpAuthParams: SRTP not active"; 274a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return false; 275a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org } 276a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org 2772e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org ASSERT(send_session_ != NULL); 278a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return send_session_->GetRtpAuthParams(key, key_len, tag_len); 279a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org} 280a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org 2810c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmvoid SrtpFilter::set_signal_silent_time(uint32_t signal_silent_time_in_ms) { 28228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org signal_silent_time_in_ms_ = signal_silent_time_in_ms; 2832e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org if (IsActive()) { 2842e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org ASSERT(send_session_ != NULL); 28528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org send_session_->set_signal_silent_time(signal_silent_time_in_ms); 2862e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org ASSERT(recv_session_ != NULL); 28728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org recv_session_->set_signal_silent_time(signal_silent_time_in_ms); 28828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (send_rtcp_session_) 28928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); 29028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (recv_rtcp_session_) 29128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); 29228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 29328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 29428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 29528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::ExpectOffer(ContentSource source) { 29628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return ((state_ == ST_INIT) || 29728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_ACTIVE) || 29828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_SENTOFFER && source == CS_LOCAL) || 29928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || 30028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || 30128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); 30228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 30328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 30428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, 30528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ContentSource source) { 30628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org offer_params_ = params; 30728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (state_ == ST_INIT) { 30828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER; 3092e7ee4b28bbdf92bdf804b600ae33679d1799788pthatcher@webrtc.org } else if (state_ == ST_ACTIVE) { 31028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org state_ = 31128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (source == CS_LOCAL) ? ST_SENTUPDATEDOFFER : ST_RECEIVEDUPDATEDOFFER; 31228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 31328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 31428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 31528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 31628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::ExpectAnswer(ContentSource source) { 31728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return ((state_ == ST_SENTOFFER && source == CS_REMOTE) || 31828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL) || 31928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_SENTUPDATEDOFFER && source == CS_REMOTE) || 32028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_LOCAL) || 32128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_SENTPRANSWER_NO_CRYPTO && source == CS_LOCAL) || 32228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_SENTPRANSWER && source == CS_LOCAL) || 32328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_RECEIVEDPRANSWER_NO_CRYPTO && source == CS_REMOTE) || 32428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (state_ == ST_RECEIVEDPRANSWER && source == CS_REMOTE)); 32528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 32628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 32728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::DoSetAnswer(const std::vector<CryptoParams>& answer_params, 32828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ContentSource source, 32928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool final) { 33028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!ExpectAnswer(source)) { 33128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Invalid state for SRTP answer"; 33228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 33328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 33428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 33528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // If the answer doesn't requests crypto complete the negotiation of an 33628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // unencrypted session. 33728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Otherwise, finalize the parameters and apply them. 33828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (answer_params.empty()) { 33928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (final) { 34028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return ResetParams(); 34128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 34228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Need to wait for the final answer to decide if 34328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // we should go to Active state. 34428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO : 34528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ST_RECEIVEDPRANSWER_NO_CRYPTO; 34628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 34728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 34828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 34928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org CryptoParams selected_params; 35028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!NegotiateParams(answer_params, &selected_params)) 35128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 35228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const CryptoParams& send_params = 35328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (source == CS_REMOTE) ? selected_params : answer_params[0]; 35428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const CryptoParams& recv_params = 35528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (source == CS_REMOTE) ? answer_params[0] : selected_params; 35628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!ApplyParams(send_params, recv_params)) { 35728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 35828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 35928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 36028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (final) { 36128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org offer_params_.clear(); 36228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org state_ = ST_ACTIVE; 36328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 36428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org state_ = 36528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER; 36628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 36728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 36828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 36928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 37028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SrtpFilter::CreateSrtpSessions() { 37128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org send_session_.reset(new SrtpSession()); 37228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org applied_send_params_ = CryptoParams(); 37328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org recv_session_.reset(new SrtpSession()); 37428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org applied_recv_params_ = CryptoParams(); 37528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 37628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SignalSrtpError.repeat(send_session_->SignalSrtpError); 37728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SignalSrtpError.repeat(recv_session_->SignalSrtpError); 37828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 37928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org send_session_->set_signal_silent_time(signal_silent_time_in_ms_); 38028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org recv_session_->set_signal_silent_time(signal_silent_time_in_ms_); 38128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 38228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 38328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, 38428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org CryptoParams* selected_params) { 38528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // We're processing an accept. We should have exactly one set of params, 38628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // unless the offer didn't mention crypto, in which case we shouldn't be here. 38728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool ret = (answer_params.size() == 1U && !offer_params_.empty()); 38828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (ret) { 38928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // We should find a match between the answer params and the offered params. 39028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::vector<CryptoParams>::const_iterator it; 39128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (it = offer_params_.begin(); it != offer_params_.end(); ++it) { 39228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (answer_params[0].Matches(*it)) { 39328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 39428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 39528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 39628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 39728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (it != offer_params_.end()) { 39828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *selected_params = *it; 39928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 40028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ret = false; 40128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 40228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 40328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 40428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!ret) { 40528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Invalid parameters in SRTP answer"; 40628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 40728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return ret; 40828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 40928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 41028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::ApplyParams(const CryptoParams& send_params, 41128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const CryptoParams& recv_params) { 41228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(jiayl): Split this method to apply send and receive CryptoParams 41328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // independently, so that we can skip one method when either send or receive 41428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // CryptoParams is unchanged. 41528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (applied_send_params_.cipher_suite == send_params.cipher_suite && 41628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org applied_send_params_.key_params == send_params.key_params && 41728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org applied_recv_params_.cipher_suite == recv_params.cipher_suite && 41828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org applied_recv_params_.key_params == recv_params.key_params) { 41928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op."; 42028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 42128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // We do not want to reset the ROC if the keys are the same. So just return. 42228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 42328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 42428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(juberti): Zero these buffers after use. 42528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool ret; 4260c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN]; 42728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) && 42828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ParseKeyParams(recv_params.key_params, recv_key, sizeof(recv_key))); 42928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (ret) { 43028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org CreateSrtpSessions(); 431521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh ret = (send_session_->SetSend( 432521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), send_key, 433521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh sizeof(send_key)) && 434521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh recv_session_->SetRecv( 435521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), recv_key, 436521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh sizeof(recv_key))); 43728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 43828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (ret) { 43928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "SRTP activated with negotiated parameters:" 44028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << " send cipher_suite " << send_params.cipher_suite 44128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << " recv cipher_suite " << recv_params.cipher_suite; 44228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org applied_send_params_ = send_params; 44328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org applied_recv_params_ = recv_params; 44428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 44528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; 44628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 44728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return ret; 44828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 44928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 45028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::ResetParams() { 45128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org offer_params_.clear(); 45228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org state_ = ST_INIT; 45377fa59d78923815ef7403bd738784e9c0be24c54guoweis send_session_ = nullptr; 45477fa59d78923815ef7403bd738784e9c0be24c54guoweis recv_session_ = nullptr; 45577fa59d78923815ef7403bd738784e9c0be24c54guoweis send_rtcp_session_ = nullptr; 45677fa59d78923815ef7403bd738784e9c0be24c54guoweis recv_rtcp_session_ = nullptr; 45728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "SRTP reset to init state"; 45828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 45928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 46028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 46128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpFilter::ParseKeyParams(const std::string& key_params, 4620c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t* key, 4630c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int len) { 46428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" 46528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 46628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Fail if key-method is wrong. 46728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (key_params.find("inline:") != 0) { 46828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 46928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 47028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 47128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Fail if base64 decode fails, or the key is the wrong size. 47228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::string key_b64(key_params.substr(7)), key_str; 473d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, 47428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org &key_str, NULL) || 47528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org static_cast<int>(key_str.size()) != len) { 47628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 47728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 47828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 47928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org memcpy(key, key_str.c_str(), len); 48028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 48128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 48228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 48328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 48428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// SrtpSession 48528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 48628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifdef HAVE_SRTP 48728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 48828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::inited_ = false; 489e70028e43fded41310d41cc93b90f2e689c04725Joachim Bauch 490cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund// This lock protects SrtpSession::inited_ and SrtpSession::sessions_. 49146ad5426b025eddac8e9232014d347e73d27180epbosrtc::GlobalLockPod SrtpSession::lock_; 49228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 49328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgSrtpSession::SrtpSession() 49428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : session_(NULL), 49528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org rtp_auth_tag_len_(0), 49628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org rtcp_auth_tag_len_(0), 49728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org srtp_stat_(new SrtpStat()), 49828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org last_send_seq_num_(-1) { 499cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund { 500cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund rtc::GlobalLockScope ls(&lock_); 501cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund sessions()->push_back(this); 502cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund } 50328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SignalSrtpError.repeat(srtp_stat_->SignalSrtpError); 50428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 50528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 50628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgSrtpSession::~SrtpSession() { 507cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund { 508cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund rtc::GlobalLockScope ls(&lock_); 509cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund sessions()->erase(std::find(sessions()->begin(), sessions()->end(), this)); 510cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund } 51128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (session_) { 51228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org srtp_dealloc(session_); 51328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 51428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 51528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 516521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shiehbool SrtpSession::SetSend(int cs, const uint8_t* key, int len) { 51728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return SetKey(ssrc_any_outbound, cs, key, len); 51828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 51928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 520521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shiehbool SrtpSession::SetRecv(int cs, const uint8_t* key, int len) { 52128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return SetKey(ssrc_any_inbound, cs, key, len); 52228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 52328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 52428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { 52528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!session_) { 52628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; 52728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 52828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 52928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 53028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int need_len = in_len + rtp_auth_tag_len_; // NOLINT 53128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (max_len < need_len) { 53228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " 53328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << max_len << " is less than the needed " << need_len; 53428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 53528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 53628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 53728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *out_len = in_len; 53828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int err = srtp_protect(session_, p, out_len); 5390c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc; 54028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (GetRtpSsrc(p, in_len, &ssrc)) { 54128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org srtp_stat_->AddProtectRtpResult(ssrc, err); 54228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 54328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int seq_num; 54428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org GetRtpSeqNum(p, in_len, &seq_num); 54528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (err != err_status_ok) { 54628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTP packet, seqnum=" 54728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << seq_num << ", err=" << err << ", last seqnum=" 54828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << last_send_seq_num_; 54928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 55028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 55128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org last_send_seq_num_ = seq_num; 55228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 55328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 55428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 5550c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool SrtpSession::ProtectRtp(void* p, 5560c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int in_len, 5570c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int max_len, 5580c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int* out_len, 5590c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int64_t* index) { 560a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org if (!ProtectRtp(p, in_len, max_len, out_len)) { 561a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return false; 562a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org } 563a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return (index) ? GetSendStreamPacketIndex(p, in_len, index) : true; 564a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org} 565a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org 56628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { 56728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!session_) { 56828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session"; 56928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 57028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 57128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 5720c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int need_len = in_len + sizeof(uint32_t) + rtcp_auth_tag_len_; // NOLINT 57328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (max_len < need_len) { 57428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length " 57528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << max_len << " is less than the needed " << need_len; 57628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 57728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 57828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 57928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *out_len = in_len; 58028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int err = srtp_protect_rtcp(session_, p, out_len); 58128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org srtp_stat_->AddProtectRtcpResult(err); 58228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (err != err_status_ok) { 58328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; 58428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 58528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 58628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 58728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 58828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 58928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { 59028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!session_) { 59128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session"; 59228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 59328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 59428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 59528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *out_len = in_len; 59628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int err = srtp_unprotect(session_, p, out_len); 5970c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc; 59828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (GetRtpSsrc(p, in_len, &ssrc)) { 59928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org srtp_stat_->AddUnprotectRtpResult(ssrc, err); 60028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 60128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (err != err_status_ok) { 60228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; 60328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 60428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 60528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 60628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 60728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 60828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { 60928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!session_) { 61028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session"; 61128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 61228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 61328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 61428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *out_len = in_len; 61528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int err = srtp_unprotect_rtcp(session_, p, out_len); 61628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org srtp_stat_->AddUnprotectRtcpResult(err); 61728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (err != err_status_ok) { 61828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; 61928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 62028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 62128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 62228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 62328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6240c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool SrtpSession::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { 625a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#if defined(ENABLE_EXTERNAL_AUTH) 626a9cf079248e1274b2ddf36ab1dc179a2b6eb9debpbos@webrtc.org ExternalHmacContext* external_hmac = NULL; 627a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org // stream_template will be the reference context for other streams. 628a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org // Let's use it for getting the keys. 629a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org srtp_stream_ctx_t* srtp_context = session_->stream_template; 630a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org if (srtp_context && srtp_context->rtp_auth) { 631a9cf079248e1274b2ddf36ab1dc179a2b6eb9debpbos@webrtc.org external_hmac = reinterpret_cast<ExternalHmacContext*>( 632a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org srtp_context->rtp_auth->state); 633a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org } 634a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org 635a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org if (!external_hmac) { 636a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org LOG(LS_ERROR) << "Failed to get auth keys from libsrtp!."; 637a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return false; 638a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org } 639a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org 640a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org *key = external_hmac->key; 641a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org *key_len = external_hmac->key_length; 642a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org *tag_len = rtp_auth_tag_len_; 643a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return true; 644a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#else 645a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return false; 646a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#endif 647a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org} 648a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org 6490c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool SrtpSession::GetSendStreamPacketIndex(void* p, 6500c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int in_len, 6510c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int64_t* index) { 652a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org srtp_hdr_t* hdr = reinterpret_cast<srtp_hdr_t*>(p); 653a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org srtp_stream_ctx_t* stream = srtp_get_stream(session_, hdr->ssrc); 654a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org if (stream == NULL) 655a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return false; 656a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org 65705376341549062f82114c96bc8d95435c00c0479henrike@webrtc.org // Shift packet index, put into network byte order 6580c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström *index = static_cast<int64_t>( 6594b3c0d6f34c379c2a06f654b62403876b20180c6Jiayang Liu rtc::NetworkToHost64(rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); 660a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return true; 661a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org} 662a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org 6630c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmvoid SrtpSession::set_signal_silent_time(uint32_t signal_silent_time_in_ms) { 66428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); 66528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 66628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 667521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shiehbool SrtpSession::SetKey(int type, int cs, const uint8_t* key, int len) { 66828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (session_) { 66928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Failed to create SRTP session: " 67028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << "SRTP session already created"; 67128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 67228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 67328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 67428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!Init()) { 67528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 67628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 67728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 67828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org srtp_policy_t policy; 67928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org memset(&policy, 0, sizeof(policy)); 68028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 681521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh if (cs == rtc::SRTP_AES128_CM_SHA1_80) { 68228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); 68328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); 684521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) { 68528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32, 68628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80 68728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 68828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" 689521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh << " cipher_suite " << cs; 69028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 69128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 69228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 69328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!key || len != SRTP_MASTER_KEY_LEN) { 69428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to create SRTP session: invalid key"; 69528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 69628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 69728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 69828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org policy.ssrc.type = static_cast<ssrc_type_t>(type); 69928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org policy.ssrc.value = 0; 7000c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström policy.key = const_cast<uint8_t*>(key); 70128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(astor) parse window size from WSH session-param 70228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org policy.window_size = 1024; 70328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org policy.allow_repeat_tx = 1; 704a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org // If external authentication option is enabled, supply custom auth module 705a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org // id EXTERNAL_HMAC_SHA1 in the policy structure. 706a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org // We want to set this option only for rtp packets. 707a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org // By default policy structure is initialized to HMAC_SHA1. 708a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#if defined(ENABLE_EXTERNAL_AUTH) 70905376341549062f82114c96bc8d95435c00c0479henrike@webrtc.org // Enable external HMAC authentication only for outgoing streams. 71005376341549062f82114c96bc8d95435c00c0479henrike@webrtc.org if (type == ssrc_any_outbound) { 71105376341549062f82114c96bc8d95435c00c0479henrike@webrtc.org policy.rtp.auth_type = EXTERNAL_HMAC_SHA1; 71205376341549062f82114c96bc8d95435c00c0479henrike@webrtc.org } 713a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#endif 71428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org policy.next = NULL; 71528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 71628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int err = srtp_create(&session_, &policy); 71728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (err != err_status_ok) { 718fec2c6d7eb58574b32eaa26222d3fb903b738cfaJoachim Bauch session_ = NULL; 71928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; 72028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 72128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 72228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 723cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund 72428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org rtp_auth_tag_len_ = policy.rtp.auth_tag_len; 72528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; 72628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 72728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 72828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 72928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::Init() { 730fec2c6d7eb58574b32eaa26222d3fb903b738cfaJoachim Bauch rtc::GlobalLockScope ls(&lock_); 731fec2c6d7eb58574b32eaa26222d3fb903b738cfaJoachim Bauch 73228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!inited_) { 73328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int err; 73428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org err = srtp_init(); 73528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (err != err_status_ok) { 73628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Failed to init SRTP, err=" << err; 73728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 73828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 73928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 74028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org err = srtp_install_event_handler(&SrtpSession::HandleEventThunk); 74128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (err != err_status_ok) { 74228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err; 74328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 74428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 745a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#if defined(ENABLE_EXTERNAL_AUTH) 746a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org err = external_crypto_init(); 747a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org if (err != err_status_ok) { 748a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err; 749a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org return false; 750a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org } 751a7b981843f35bb6c26cf3bc95b5a00a0b9f50a93henrike@webrtc.org#endif 75228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org inited_ = true; 75328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 75428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 75528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 75628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 75728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7589dba52562725dbaced0d671982201ede753d72e8wu@webrtc.orgvoid SrtpSession::Terminate() { 759fec2c6d7eb58574b32eaa26222d3fb903b738cfaJoachim Bauch rtc::GlobalLockScope ls(&lock_); 760fec2c6d7eb58574b32eaa26222d3fb903b738cfaJoachim Bauch 7619dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org if (inited_) { 7629dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org int err = srtp_shutdown(); 7639dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org if (err) { 7649dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err; 7659dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org return; 7669dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org } 7679dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org inited_ = false; 7689dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org } 7699dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org} 7709dba52562725dbaced0d671982201ede753d72e8wu@webrtc.org 77128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SrtpSession::HandleEvent(const srtp_event_data_t* ev) { 77228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org switch (ev->event) { 77328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case event_ssrc_collision: 77428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: SSRC collision"; 77528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 77628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case event_key_soft_limit: 77728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: reached soft key usage limit"; 77828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 77928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case event_key_hard_limit: 78028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: reached hard key usage limit"; 78128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 78228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case event_packet_index_limit: 78328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)"; 78428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 78528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org default: 78628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "SRTP event: unknown " << ev->event; 78728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 78828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 78928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 79028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 79128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { 792cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund rtc::GlobalLockScope ls(&lock_); 793cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund 794cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund for (std::list<SrtpSession*>::iterator it = sessions()->begin(); 795cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund it != sessions()->end(); ++it) { 796cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund if ((*it)->session_ == ev->session) { 797cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund (*it)->HandleEvent(ev); 798cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund break; 799cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund } 80028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 80128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 80228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 803cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglundstd::list<SrtpSession*>* SrtpSession::sessions() { 804cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund RTC_DEFINE_STATIC_LOCAL(std::list<SrtpSession*>, sessions, ()); 805cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund return &sessions; 806cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund} 807cbe9f51cf85a5aeb20a5134dad56cd2b527c098dphoglund 80828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#else // !HAVE_SRTP 80928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 81028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// On some systems, SRTP is not (yet) available. 81128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 81228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgSrtpSession::SrtpSession() { 81328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(WARNING) << "SRTP implementation is missing."; 81428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 81528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 81628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgSrtpSession::~SrtpSession() { 81728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 81828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8190c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool SrtpSession::SetSend(const std::string& cs, const uint8_t* key, int len) { 82028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 82128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 82228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8230c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool SrtpSession::SetRecv(const std::string& cs, const uint8_t* key, int len) { 82428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 82528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 82628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 82728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::ProtectRtp(void* data, int in_len, int max_len, 82828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int* out_len) { 82928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 83028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 83128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 83228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::ProtectRtcp(void* data, int in_len, int max_len, 83328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int* out_len) { 83428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 83528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 83628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 83728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::UnprotectRtp(void* data, int in_len, int* out_len) { 83828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 83928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 84028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 84128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool SrtpSession::UnprotectRtcp(void* data, int in_len, int* out_len) { 84228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return SrtpNotAvailable(__FUNCTION__); 84328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 84428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8450c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmvoid SrtpSession::set_signal_silent_time(uint32_t signal_silent_time) { 84628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Do nothing. 84728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 84828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 84928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif // HAVE_SRTP 85028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 85128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 85228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// SrtpStat 85328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 85428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifdef HAVE_SRTP 85528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 85628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgSrtpStat::SrtpStat() 85728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : signal_silent_time_(1000) { 85828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 85928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8600c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmvoid SrtpStat::AddProtectRtpResult(uint32_t ssrc, int result) { 86128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org FailureKey key; 86228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.ssrc = ssrc; 86328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.mode = SrtpFilter::PROTECT; 86428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org switch (result) { 86528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case err_status_ok: 86628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.error = SrtpFilter::ERROR_NONE; 86728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 86828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case err_status_auth_fail: 86928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.error = SrtpFilter::ERROR_AUTH; 87028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 87128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org default: 87228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.error = SrtpFilter::ERROR_FAIL; 87328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 87428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org HandleSrtpResult(key); 87528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 87628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8770c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmvoid SrtpStat::AddUnprotectRtpResult(uint32_t ssrc, int result) { 87828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org FailureKey key; 87928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.ssrc = ssrc; 88028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.mode = SrtpFilter::UNPROTECT; 88128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org switch (result) { 88228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case err_status_ok: 88328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.error = SrtpFilter::ERROR_NONE; 88428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 88528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case err_status_auth_fail: 88628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.error = SrtpFilter::ERROR_AUTH; 88728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 88828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case err_status_replay_fail: 88928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case err_status_replay_old: 89028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.error = SrtpFilter::ERROR_REPLAY; 89128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 89228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org default: 89328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org key.error = SrtpFilter::ERROR_FAIL; 89428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 89528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org HandleSrtpResult(key); 89628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 89728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 89828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SrtpStat::AddProtectRtcpResult(int result) { 89928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org AddProtectRtpResult(0U, result); 90028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 90128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 90228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SrtpStat::AddUnprotectRtcpResult(int result) { 90328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org AddUnprotectRtpResult(0U, result); 90428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 90528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 90628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { 90728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Handle some cases where error should be signalled right away. For other 90828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // errors, trigger error for the first time seeing it. After that, silent 90928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // the same error for a certain amount of time (default 1 sec). 91028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (key.error != SrtpFilter::ERROR_NONE) { 91128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // For errors, signal first time and wait for 1 sec. 91228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org FailureStat* stat = &(failures_[key]); 9130c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t current_time = rtc::Time(); 91428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (stat->last_signal_time == 0 || 915d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::TimeDiff(current_time, stat->last_signal_time) > 91628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org static_cast<int>(signal_silent_time_)) { 91728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SignalSrtpError(key.ssrc, key.mode, key.error); 91828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org stat->last_signal_time = current_time; 91928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 92028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 92128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 92228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 92328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#else // !HAVE_SRTP 92428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 92528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// On some systems, SRTP is not (yet) available. 92628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 92728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgSrtpStat::SrtpStat() 92828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : signal_silent_time_(1000) { 92928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(WARNING) << "SRTP implementation is missing."; 93028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 93128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9320c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmvoid SrtpStat::AddProtectRtpResult(uint32_t ssrc, int result) { 93328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 93428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 93528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9360c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmvoid SrtpStat::AddUnprotectRtpResult(uint32_t ssrc, int result) { 93728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 93828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 93928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 94028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SrtpStat::AddProtectRtcpResult(int result) { 94128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 94228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 94328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 94428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SrtpStat::AddUnprotectRtcpResult(int result) { 94528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 94628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 94728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 94828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { 94928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SrtpNotAvailable(__FUNCTION__); 95028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 95128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 95228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif // HAVE_SRTP 95328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 95428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} // namespace cricket 955