1 /* 2 * libjingle 3 * Copyright 2009 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #undef HAVE_CONFIG_H 29 30 #include "talk/session/media/srtpfilter.h" 31 32 #include <algorithm> 33 #include <cstring> 34 35 #include "talk/base/base64.h" 36 #include "talk/base/logging.h" 37 #include "talk/base/stringencode.h" 38 #include "talk/base/timeutils.h" 39 #include "talk/media/base/rtputils.h" 40 41 // Enable this line to turn on SRTP debugging 42 // #define SRTP_DEBUG 43 44 #ifdef HAVE_SRTP 45 #ifdef SRTP_RELATIVE_PATH 46 #include "srtp.h" // NOLINT 47 #else 48 #include "third_party/libsrtp/include/srtp.h" 49 #endif // SRTP_RELATIVE_PATH 50 #ifdef _DEBUG 51 extern "C" debug_module_t mod_srtp; 52 extern "C" debug_module_t mod_auth; 53 extern "C" debug_module_t mod_cipher; 54 extern "C" debug_module_t mod_stat; 55 extern "C" debug_module_t mod_alloc; 56 extern "C" debug_module_t mod_aes_icm; 57 extern "C" debug_module_t mod_aes_hmac; 58 #endif 59 #else 60 // SrtpFilter needs that constant. 61 #define SRTP_MASTER_KEY_LEN 30 62 #endif // HAVE_SRTP 63 64 namespace cricket { 65 66 const char CS_AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80"; 67 const char CS_AES_CM_128_HMAC_SHA1_32[] = "AES_CM_128_HMAC_SHA1_32"; 68 const int SRTP_MASTER_KEY_BASE64_LEN = SRTP_MASTER_KEY_LEN * 4 / 3; 69 const int SRTP_MASTER_KEY_KEY_LEN = 16; 70 const int SRTP_MASTER_KEY_SALT_LEN = 14; 71 72 #ifndef HAVE_SRTP 73 74 // This helper function is used on systems that don't (yet) have SRTP, 75 // to log that the functions that require it won't do anything. 76 namespace { 77 bool SrtpNotAvailable(const char *func) { 78 LOG(LS_ERROR) << func << ": SRTP is not available on your system."; 79 return false; 80 } 81 } // anonymous namespace 82 83 #endif // !HAVE_SRTP 84 85 void EnableSrtpDebugging() { 86 #ifdef HAVE_SRTP 87 #ifdef _DEBUG 88 debug_on(mod_srtp); 89 debug_on(mod_auth); 90 debug_on(mod_cipher); 91 debug_on(mod_stat); 92 debug_on(mod_alloc); 93 debug_on(mod_aes_icm); 94 // debug_on(mod_aes_cbc); 95 // debug_on(mod_hmac); 96 #endif 97 #endif // HAVE_SRTP 98 } 99 100 // NOTE: This is called from ChannelManager D'tor. 101 void ShutdownSrtp() { 102 #ifdef HAVE_SRTP 103 // If srtp_dealloc is not executed then this will clear all existing sessions. 104 // This should be called when application is shutting down. 105 SrtpSession::Terminate(); 106 #endif 107 } 108 109 SrtpFilter::SrtpFilter() 110 : state_(ST_INIT), 111 signal_silent_time_in_ms_(0) { 112 } 113 114 SrtpFilter::~SrtpFilter() { 115 } 116 117 bool SrtpFilter::IsActive() const { 118 return state_ >= ST_ACTIVE; 119 } 120 121 bool SrtpFilter::SetOffer(const std::vector<CryptoParams>& offer_params, 122 ContentSource source) { 123 if (!ExpectOffer(source)) { 124 LOG(LS_ERROR) << "Wrong state to update SRTP offer"; 125 return false; 126 } 127 return StoreParams(offer_params, source); 128 } 129 130 bool SrtpFilter::SetAnswer(const std::vector<CryptoParams>& answer_params, 131 ContentSource source) { 132 return DoSetAnswer(answer_params, source, true); 133 } 134 135 bool SrtpFilter::SetProvisionalAnswer( 136 const std::vector<CryptoParams>& answer_params, 137 ContentSource source) { 138 return DoSetAnswer(answer_params, source, false); 139 } 140 141 bool SrtpFilter::SetRtpParams(const std::string& send_cs, 142 const uint8* send_key, int send_key_len, 143 const std::string& recv_cs, 144 const uint8* recv_key, int recv_key_len) { 145 if (state_ == ST_ACTIVE) { 146 LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active"; 147 return false; 148 } 149 CreateSrtpSessions(); 150 if (!send_session_->SetSend(send_cs, send_key, send_key_len)) 151 return false; 152 153 if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) 154 return false; 155 156 state_ = ST_ACTIVE; 157 158 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" 159 << " send cipher_suite " << send_cs 160 << " recv cipher_suite " << recv_cs; 161 162 return true; 163 } 164 165 // This function is provided separately because DTLS-SRTP behaves 166 // differently in RTP/RTCP mux and non-mux modes. 167 // 168 // - In the non-muxed case, RTP and RTCP are keyed with different 169 // keys (from different DTLS handshakes), and so we need a new 170 // SrtpSession. 171 // - In the muxed case, they are keyed with the same keys, so 172 // this function is not needed 173 bool SrtpFilter::SetRtcpParams(const std::string& send_cs, 174 const uint8* send_key, int send_key_len, 175 const std::string& recv_cs, 176 const uint8* recv_key, int recv_key_len) { 177 // This can only be called once, but can be safely called after 178 // SetRtpParams 179 if (send_rtcp_session_ || recv_rtcp_session_) { 180 LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; 181 return false; 182 } 183 184 send_rtcp_session_.reset(new SrtpSession()); 185 SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError); 186 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); 187 if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) 188 return false; 189 190 recv_rtcp_session_.reset(new SrtpSession()); 191 SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError); 192 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); 193 if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) 194 return false; 195 196 LOG(LS_INFO) << "SRTCP activated with negotiated parameters:" 197 << " send cipher_suite " << send_cs 198 << " recv cipher_suite " << recv_cs; 199 200 return true; 201 } 202 203 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { 204 if (!IsActive()) { 205 LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; 206 return false; 207 } 208 return send_session_->ProtectRtp(p, in_len, max_len, out_len); 209 } 210 211 bool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { 212 if (!IsActive()) { 213 LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active"; 214 return false; 215 } 216 if (send_rtcp_session_) { 217 return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len); 218 } else { 219 return send_session_->ProtectRtcp(p, in_len, max_len, out_len); 220 } 221 } 222 223 bool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) { 224 if (!IsActive()) { 225 LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active"; 226 return false; 227 } 228 return recv_session_->UnprotectRtp(p, in_len, out_len); 229 } 230 231 bool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) { 232 if (!IsActive()) { 233 LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active"; 234 return false; 235 } 236 if (recv_rtcp_session_) { 237 return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len); 238 } else { 239 return recv_session_->UnprotectRtcp(p, in_len, out_len); 240 } 241 } 242 243 void SrtpFilter::set_signal_silent_time(uint32 signal_silent_time_in_ms) { 244 signal_silent_time_in_ms_ = signal_silent_time_in_ms; 245 if (state_ == ST_ACTIVE) { 246 send_session_->set_signal_silent_time(signal_silent_time_in_ms); 247 recv_session_->set_signal_silent_time(signal_silent_time_in_ms); 248 if (send_rtcp_session_) 249 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); 250 if (recv_rtcp_session_) 251 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); 252 } 253 } 254 255 bool SrtpFilter::ExpectOffer(ContentSource source) { 256 return ((state_ == ST_INIT) || 257 (state_ == ST_ACTIVE) || 258 (state_ == ST_SENTOFFER && source == CS_LOCAL) || 259 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || 260 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || 261 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); 262 } 263 264 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, 265 ContentSource source) { 266 offer_params_ = params; 267 if (state_ == ST_INIT) { 268 state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER; 269 } else { // state >= ST_ACTIVE 270 state_ = 271 (source == CS_LOCAL) ? ST_SENTUPDATEDOFFER : ST_RECEIVEDUPDATEDOFFER; 272 } 273 return true; 274 } 275 276 bool SrtpFilter::ExpectAnswer(ContentSource source) { 277 return ((state_ == ST_SENTOFFER && source == CS_REMOTE) || 278 (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL) || 279 (state_ == ST_SENTUPDATEDOFFER && source == CS_REMOTE) || 280 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_LOCAL) || 281 (state_ == ST_SENTPRANSWER_NO_CRYPTO && source == CS_LOCAL) || 282 (state_ == ST_SENTPRANSWER && source == CS_LOCAL) || 283 (state_ == ST_RECEIVEDPRANSWER_NO_CRYPTO && source == CS_REMOTE) || 284 (state_ == ST_RECEIVEDPRANSWER && source == CS_REMOTE)); 285 } 286 287 bool SrtpFilter::DoSetAnswer(const std::vector<CryptoParams>& answer_params, 288 ContentSource source, 289 bool final) { 290 if (!ExpectAnswer(source)) { 291 LOG(LS_ERROR) << "Invalid state for SRTP answer"; 292 return false; 293 } 294 295 // If the answer doesn't requests crypto complete the negotiation of an 296 // unencrypted session. 297 // Otherwise, finalize the parameters and apply them. 298 if (answer_params.empty()) { 299 if (final) { 300 return ResetParams(); 301 } else { 302 // Need to wait for the final answer to decide if 303 // we should go to Active state. 304 state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO : 305 ST_RECEIVEDPRANSWER_NO_CRYPTO; 306 return true; 307 } 308 } 309 CryptoParams selected_params; 310 if (!NegotiateParams(answer_params, &selected_params)) 311 return false; 312 const CryptoParams& send_params = 313 (source == CS_REMOTE) ? selected_params : answer_params[0]; 314 const CryptoParams& recv_params = 315 (source == CS_REMOTE) ? answer_params[0] : selected_params; 316 if (!ApplyParams(send_params, recv_params)) { 317 return false; 318 } 319 320 if (final) { 321 offer_params_.clear(); 322 state_ = ST_ACTIVE; 323 } else { 324 state_ = 325 (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER; 326 } 327 return true; 328 } 329 330 void SrtpFilter::CreateSrtpSessions() { 331 send_session_.reset(new SrtpSession()); 332 applied_send_params_ = CryptoParams(); 333 recv_session_.reset(new SrtpSession()); 334 applied_recv_params_ = CryptoParams(); 335 336 SignalSrtpError.repeat(send_session_->SignalSrtpError); 337 SignalSrtpError.repeat(recv_session_->SignalSrtpError); 338 339 send_session_->set_signal_silent_time(signal_silent_time_in_ms_); 340 recv_session_->set_signal_silent_time(signal_silent_time_in_ms_); 341 } 342 343 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, 344 CryptoParams* selected_params) { 345 // We're processing an accept. We should have exactly one set of params, 346 // unless the offer didn't mention crypto, in which case we shouldn't be here. 347 bool ret = (answer_params.size() == 1U && !offer_params_.empty()); 348 if (ret) { 349 // We should find a match between the answer params and the offered params. 350 std::vector<CryptoParams>::const_iterator it; 351 for (it = offer_params_.begin(); it != offer_params_.end(); ++it) { 352 if (answer_params[0].Matches(*it)) { 353 break; 354 } 355 } 356 357 if (it != offer_params_.end()) { 358 *selected_params = *it; 359 } else { 360 ret = false; 361 } 362 } 363 364 if (!ret) { 365 LOG(LS_WARNING) << "Invalid parameters in SRTP answer"; 366 } 367 return ret; 368 } 369 370 bool SrtpFilter::ApplyParams(const CryptoParams& send_params, 371 const CryptoParams& recv_params) { 372 // TODO(jiayl): Split this method to apply send and receive CryptoParams 373 // independently, so that we can skip one method when either send or receive 374 // CryptoParams is unchanged. 375 if (applied_send_params_.cipher_suite == send_params.cipher_suite && 376 applied_send_params_.key_params == send_params.key_params && 377 applied_recv_params_.cipher_suite == recv_params.cipher_suite && 378 applied_recv_params_.key_params == recv_params.key_params) { 379 LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op."; 380 381 // We do not want to reset the ROC if the keys are the same. So just return. 382 return true; 383 } 384 // TODO(juberti): Zero these buffers after use. 385 bool ret; 386 uint8 send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN]; 387 ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) && 388 ParseKeyParams(recv_params.key_params, recv_key, sizeof(recv_key))); 389 if (ret) { 390 CreateSrtpSessions(); 391 ret = (send_session_->SetSend(send_params.cipher_suite, 392 send_key, sizeof(send_key)) && 393 recv_session_->SetRecv(recv_params.cipher_suite, 394 recv_key, sizeof(recv_key))); 395 } 396 if (ret) { 397 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" 398 << " send cipher_suite " << send_params.cipher_suite 399 << " recv cipher_suite " << recv_params.cipher_suite; 400 applied_send_params_ = send_params; 401 applied_recv_params_ = recv_params; 402 } else { 403 LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; 404 } 405 return ret; 406 } 407 408 bool SrtpFilter::ResetParams() { 409 offer_params_.clear(); 410 state_ = ST_INIT; 411 LOG(LS_INFO) << "SRTP reset to init state"; 412 return true; 413 } 414 415 bool SrtpFilter::ParseKeyParams(const std::string& key_params, 416 uint8* key, int len) { 417 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" 418 419 // Fail if key-method is wrong. 420 if (key_params.find("inline:") != 0) { 421 return false; 422 } 423 424 // Fail if base64 decode fails, or the key is the wrong size. 425 std::string key_b64(key_params.substr(7)), key_str; 426 if (!talk_base::Base64::Decode(key_b64, talk_base::Base64::DO_STRICT, 427 &key_str, NULL) || 428 static_cast<int>(key_str.size()) != len) { 429 return false; 430 } 431 432 memcpy(key, key_str.c_str(), len); 433 return true; 434 } 435 436 /////////////////////////////////////////////////////////////////////////////// 437 // SrtpSession 438 439 #ifdef HAVE_SRTP 440 441 bool SrtpSession::inited_ = false; 442 443 SrtpSession::SrtpSession() 444 : session_(NULL), 445 rtp_auth_tag_len_(0), 446 rtcp_auth_tag_len_(0), 447 srtp_stat_(new SrtpStat()), 448 last_send_seq_num_(-1) { 449 sessions()->push_back(this); 450 SignalSrtpError.repeat(srtp_stat_->SignalSrtpError); 451 } 452 453 SrtpSession::~SrtpSession() { 454 sessions()->erase(std::find(sessions()->begin(), sessions()->end(), this)); 455 if (session_) { 456 srtp_dealloc(session_); 457 } 458 } 459 460 bool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) { 461 return SetKey(ssrc_any_outbound, cs, key, len); 462 } 463 464 bool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) { 465 return SetKey(ssrc_any_inbound, cs, key, len); 466 } 467 468 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { 469 if (!session_) { 470 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; 471 return false; 472 } 473 474 int need_len = in_len + rtp_auth_tag_len_; // NOLINT 475 if (max_len < need_len) { 476 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " 477 << max_len << " is less than the needed " << need_len; 478 return false; 479 } 480 481 *out_len = in_len; 482 int err = srtp_protect(session_, p, out_len); 483 uint32 ssrc; 484 if (GetRtpSsrc(p, in_len, &ssrc)) { 485 srtp_stat_->AddProtectRtpResult(ssrc, err); 486 } 487 int seq_num; 488 GetRtpSeqNum(p, in_len, &seq_num); 489 if (err != err_status_ok) { 490 LOG(LS_WARNING) << "Failed to protect SRTP packet, seqnum=" 491 << seq_num << ", err=" << err << ", last seqnum=" 492 << last_send_seq_num_; 493 return false; 494 } 495 last_send_seq_num_ = seq_num; 496 return true; 497 } 498 499 bool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { 500 if (!session_) { 501 LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session"; 502 return false; 503 } 504 505 int need_len = in_len + sizeof(uint32) + rtcp_auth_tag_len_; // NOLINT 506 if (max_len < need_len) { 507 LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length " 508 << max_len << " is less than the needed " << need_len; 509 return false; 510 } 511 512 *out_len = in_len; 513 int err = srtp_protect_rtcp(session_, p, out_len); 514 srtp_stat_->AddProtectRtcpResult(err); 515 if (err != err_status_ok) { 516 LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; 517 return false; 518 } 519 return true; 520 } 521 522 bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { 523 if (!session_) { 524 LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session"; 525 return false; 526 } 527 528 *out_len = in_len; 529 int err = srtp_unprotect(session_, p, out_len); 530 uint32 ssrc; 531 if (GetRtpSsrc(p, in_len, &ssrc)) { 532 srtp_stat_->AddUnprotectRtpResult(ssrc, err); 533 } 534 if (err != err_status_ok) { 535 LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; 536 return false; 537 } 538 return true; 539 } 540 541 bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { 542 if (!session_) { 543 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session"; 544 return false; 545 } 546 547 *out_len = in_len; 548 int err = srtp_unprotect_rtcp(session_, p, out_len); 549 srtp_stat_->AddUnprotectRtcpResult(err); 550 if (err != err_status_ok) { 551 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; 552 return false; 553 } 554 return true; 555 } 556 557 void SrtpSession::set_signal_silent_time(uint32 signal_silent_time_in_ms) { 558 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); 559 } 560 561 bool SrtpSession::SetKey(int type, const std::string& cs, 562 const uint8* key, int len) { 563 if (session_) { 564 LOG(LS_ERROR) << "Failed to create SRTP session: " 565 << "SRTP session already created"; 566 return false; 567 } 568 569 if (!Init()) { 570 return false; 571 } 572 573 srtp_policy_t policy; 574 memset(&policy, 0, sizeof(policy)); 575 576 if (cs == CS_AES_CM_128_HMAC_SHA1_80) { 577 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); 578 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); 579 } else if (cs == CS_AES_CM_128_HMAC_SHA1_32) { 580 crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32, 581 crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80 582 } else { 583 LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" 584 << " cipher_suite " << cs.c_str(); 585 return false; 586 } 587 588 if (!key || len != SRTP_MASTER_KEY_LEN) { 589 LOG(LS_WARNING) << "Failed to create SRTP session: invalid key"; 590 return false; 591 } 592 593 policy.ssrc.type = static_cast<ssrc_type_t>(type); 594 policy.ssrc.value = 0; 595 policy.key = const_cast<uint8*>(key); 596 // TODO(astor) parse window size from WSH session-param 597 policy.window_size = 1024; 598 policy.allow_repeat_tx = 1; 599 policy.next = NULL; 600 601 int err = srtp_create(&session_, &policy); 602 if (err != err_status_ok) { 603 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; 604 return false; 605 } 606 607 rtp_auth_tag_len_ = policy.rtp.auth_tag_len; 608 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; 609 return true; 610 } 611 612 bool SrtpSession::Init() { 613 if (!inited_) { 614 int err; 615 err = srtp_init(); 616 if (err != err_status_ok) { 617 LOG(LS_ERROR) << "Failed to init SRTP, err=" << err; 618 return false; 619 } 620 621 err = srtp_install_event_handler(&SrtpSession::HandleEventThunk); 622 if (err != err_status_ok) { 623 LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err; 624 return false; 625 } 626 627 inited_ = true; 628 } 629 630 return true; 631 } 632 633 void SrtpSession::Terminate() { 634 if (inited_) { 635 int err = srtp_shutdown(); 636 if (err) { 637 LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err; 638 return; 639 } 640 inited_ = false; 641 } 642 } 643 644 void SrtpSession::HandleEvent(const srtp_event_data_t* ev) { 645 switch (ev->event) { 646 case event_ssrc_collision: 647 LOG(LS_INFO) << "SRTP event: SSRC collision"; 648 break; 649 case event_key_soft_limit: 650 LOG(LS_INFO) << "SRTP event: reached soft key usage limit"; 651 break; 652 case event_key_hard_limit: 653 LOG(LS_INFO) << "SRTP event: reached hard key usage limit"; 654 break; 655 case event_packet_index_limit: 656 LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)"; 657 break; 658 default: 659 LOG(LS_INFO) << "SRTP event: unknown " << ev->event; 660 break; 661 } 662 } 663 664 void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { 665 for (std::list<SrtpSession*>::iterator it = sessions()->begin(); 666 it != sessions()->end(); ++it) { 667 if ((*it)->session_ == ev->session) { 668 (*it)->HandleEvent(ev); 669 break; 670 } 671 } 672 } 673 674 std::list<SrtpSession*>* SrtpSession::sessions() { 675 LIBJINGLE_DEFINE_STATIC_LOCAL(std::list<SrtpSession*>, sessions, ()); 676 return &sessions; 677 } 678 679 #else // !HAVE_SRTP 680 681 // On some systems, SRTP is not (yet) available. 682 683 SrtpSession::SrtpSession() { 684 LOG(WARNING) << "SRTP implementation is missing."; 685 } 686 687 SrtpSession::~SrtpSession() { 688 } 689 690 bool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) { 691 return SrtpNotAvailable(__FUNCTION__); 692 } 693 694 bool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) { 695 return SrtpNotAvailable(__FUNCTION__); 696 } 697 698 bool SrtpSession::ProtectRtp(void* data, int in_len, int max_len, 699 int* out_len) { 700 return SrtpNotAvailable(__FUNCTION__); 701 } 702 703 bool SrtpSession::ProtectRtcp(void* data, int in_len, int max_len, 704 int* out_len) { 705 return SrtpNotAvailable(__FUNCTION__); 706 } 707 708 bool SrtpSession::UnprotectRtp(void* data, int in_len, int* out_len) { 709 return SrtpNotAvailable(__FUNCTION__); 710 } 711 712 bool SrtpSession::UnprotectRtcp(void* data, int in_len, int* out_len) { 713 return SrtpNotAvailable(__FUNCTION__); 714 } 715 716 void SrtpSession::set_signal_silent_time(uint32 signal_silent_time) { 717 // Do nothing. 718 } 719 720 #endif // HAVE_SRTP 721 722 /////////////////////////////////////////////////////////////////////////////// 723 // SrtpStat 724 725 #ifdef HAVE_SRTP 726 727 SrtpStat::SrtpStat() 728 : signal_silent_time_(1000) { 729 } 730 731 void SrtpStat::AddProtectRtpResult(uint32 ssrc, int result) { 732 FailureKey key; 733 key.ssrc = ssrc; 734 key.mode = SrtpFilter::PROTECT; 735 switch (result) { 736 case err_status_ok: 737 key.error = SrtpFilter::ERROR_NONE; 738 break; 739 case err_status_auth_fail: 740 key.error = SrtpFilter::ERROR_AUTH; 741 break; 742 default: 743 key.error = SrtpFilter::ERROR_FAIL; 744 } 745 HandleSrtpResult(key); 746 } 747 748 void SrtpStat::AddUnprotectRtpResult(uint32 ssrc, int result) { 749 FailureKey key; 750 key.ssrc = ssrc; 751 key.mode = SrtpFilter::UNPROTECT; 752 switch (result) { 753 case err_status_ok: 754 key.error = SrtpFilter::ERROR_NONE; 755 break; 756 case err_status_auth_fail: 757 key.error = SrtpFilter::ERROR_AUTH; 758 break; 759 case err_status_replay_fail: 760 case err_status_replay_old: 761 key.error = SrtpFilter::ERROR_REPLAY; 762 break; 763 default: 764 key.error = SrtpFilter::ERROR_FAIL; 765 } 766 HandleSrtpResult(key); 767 } 768 769 void SrtpStat::AddProtectRtcpResult(int result) { 770 AddProtectRtpResult(0U, result); 771 } 772 773 void SrtpStat::AddUnprotectRtcpResult(int result) { 774 AddUnprotectRtpResult(0U, result); 775 } 776 777 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { 778 // Handle some cases where error should be signalled right away. For other 779 // errors, trigger error for the first time seeing it. After that, silent 780 // the same error for a certain amount of time (default 1 sec). 781 if (key.error != SrtpFilter::ERROR_NONE) { 782 // For errors, signal first time and wait for 1 sec. 783 FailureStat* stat = &(failures_[key]); 784 uint32 current_time = talk_base::Time(); 785 if (stat->last_signal_time == 0 || 786 talk_base::TimeDiff(current_time, stat->last_signal_time) > 787 static_cast<int>(signal_silent_time_)) { 788 SignalSrtpError(key.ssrc, key.mode, key.error); 789 stat->last_signal_time = current_time; 790 } 791 } 792 } 793 794 #else // !HAVE_SRTP 795 796 // On some systems, SRTP is not (yet) available. 797 798 SrtpStat::SrtpStat() 799 : signal_silent_time_(1000) { 800 LOG(WARNING) << "SRTP implementation is missing."; 801 } 802 803 void SrtpStat::AddProtectRtpResult(uint32 ssrc, int result) { 804 SrtpNotAvailable(__FUNCTION__); 805 } 806 807 void SrtpStat::AddUnprotectRtpResult(uint32 ssrc, int result) { 808 SrtpNotAvailable(__FUNCTION__); 809 } 810 811 void SrtpStat::AddProtectRtcpResult(int result) { 812 SrtpNotAvailable(__FUNCTION__); 813 } 814 815 void SrtpStat::AddUnprotectRtcpResult(int result) { 816 SrtpNotAvailable(__FUNCTION__); 817 } 818 819 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { 820 SrtpNotAvailable(__FUNCTION__); 821 } 822 823 #endif // HAVE_SRTP 824 825 } // namespace cricket 826