| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2009 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 const uint8_t* recv_key, | 106 const uint8_t* recv_key, |
| 107 int recv_key_len) { | 107 int recv_key_len) { |
| 108 // This can only be called once, but can be safely called after | 108 // This can only be called once, but can be safely called after |
| 109 // SetRtpParams | 109 // SetRtpParams |
| 110 if (send_rtcp_session_ || recv_rtcp_session_) { | 110 if (send_rtcp_session_ || recv_rtcp_session_) { |
| 111 LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; | 111 LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; |
| 112 return false; | 112 return false; |
| 113 } | 113 } |
| 114 | 114 |
| 115 send_rtcp_session_.reset(new SrtpSession()); | 115 send_rtcp_session_.reset(new SrtpSession()); |
| 116 SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError); | |
| 117 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); | |
| 118 if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) | 116 if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) |
| 119 return false; | 117 return false; |
| 120 | 118 |
| 121 recv_rtcp_session_.reset(new SrtpSession()); | 119 recv_rtcp_session_.reset(new SrtpSession()); |
| 122 SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError); | |
| 123 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); | |
| 124 if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) | 120 if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) |
| 125 return false; | 121 return false; |
| 126 | 122 |
| 127 LOG(LS_INFO) << "SRTCP activated with negotiated parameters:" | 123 LOG(LS_INFO) << "SRTCP activated with negotiated parameters:" |
| 128 << " send cipher_suite " << send_cs | 124 << " send cipher_suite " << send_cs |
| 129 << " recv cipher_suite " << recv_cs; | 125 << " recv cipher_suite " << recv_cs; |
| 130 | 126 |
| 131 return true; | 127 return true; |
| 132 } | 128 } |
| 133 | 129 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 bool SrtpFilter::IsExternalAuthActive() const { | 217 bool SrtpFilter::IsExternalAuthActive() const { |
| 222 if (!IsActive()) { | 218 if (!IsActive()) { |
| 223 LOG(LS_WARNING) << "Failed to check IsExternalAuthActive: SRTP not active"; | 219 LOG(LS_WARNING) << "Failed to check IsExternalAuthActive: SRTP not active"; |
| 224 return false; | 220 return false; |
| 225 } | 221 } |
| 226 | 222 |
| 227 RTC_CHECK(send_session_); | 223 RTC_CHECK(send_session_); |
| 228 return send_session_->IsExternalAuthActive(); | 224 return send_session_->IsExternalAuthActive(); |
| 229 } | 225 } |
| 230 | 226 |
| 231 void SrtpFilter::set_signal_silent_time(int signal_silent_time_in_ms) { | |
| 232 signal_silent_time_in_ms_ = signal_silent_time_in_ms; | |
| 233 if (IsActive()) { | |
| 234 RTC_CHECK(send_session_); | |
| 235 send_session_->set_signal_silent_time(signal_silent_time_in_ms); | |
| 236 RTC_CHECK(recv_session_); | |
| 237 recv_session_->set_signal_silent_time(signal_silent_time_in_ms); | |
| 238 if (send_rtcp_session_) | |
| 239 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); | |
| 240 if (recv_rtcp_session_) | |
| 241 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); | |
| 242 } | |
| 243 } | |
| 244 | |
| 245 bool SrtpFilter::ExpectOffer(ContentSource source) { | 227 bool SrtpFilter::ExpectOffer(ContentSource source) { |
| 246 return ((state_ == ST_INIT) || | 228 return ((state_ == ST_INIT) || |
| 247 (state_ == ST_ACTIVE) || | 229 (state_ == ST_ACTIVE) || |
| 248 (state_ == ST_SENTOFFER && source == CS_LOCAL) || | 230 (state_ == ST_SENTOFFER && source == CS_LOCAL) || |
| 249 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || | 231 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || |
| 250 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || | 232 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || |
| 251 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); | 233 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); |
| 252 } | 234 } |
| 253 | 235 |
| 254 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, | 236 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 } | 298 } |
| 317 return true; | 299 return true; |
| 318 } | 300 } |
| 319 | 301 |
| 320 void SrtpFilter::CreateSrtpSessions() { | 302 void SrtpFilter::CreateSrtpSessions() { |
| 321 send_session_.reset(new SrtpSession()); | 303 send_session_.reset(new SrtpSession()); |
| 322 applied_send_params_ = CryptoParams(); | 304 applied_send_params_ = CryptoParams(); |
| 323 recv_session_.reset(new SrtpSession()); | 305 recv_session_.reset(new SrtpSession()); |
| 324 applied_recv_params_ = CryptoParams(); | 306 applied_recv_params_ = CryptoParams(); |
| 325 | 307 |
| 326 SignalSrtpError.repeat(send_session_->SignalSrtpError); | |
| 327 SignalSrtpError.repeat(recv_session_->SignalSrtpError); | |
| 328 | |
| 329 send_session_->set_signal_silent_time(signal_silent_time_in_ms_); | |
| 330 recv_session_->set_signal_silent_time(signal_silent_time_in_ms_); | |
| 331 if (external_auth_enabled_) { | 308 if (external_auth_enabled_) { |
| 332 send_session_->EnableExternalAuth(); | 309 send_session_->EnableExternalAuth(); |
| 333 } | 310 } |
| 334 } | 311 } |
| 335 | 312 |
| 336 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, | 313 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, |
| 337 CryptoParams* selected_params) { | 314 CryptoParams* selected_params) { |
| 338 // We're processing an accept. We should have exactly one set of params, | 315 // We're processing an accept. We should have exactly one set of params, |
| 339 // unless the offer didn't mention crypto, in which case we shouldn't be here. | 316 // unless the offer didn't mention crypto, in which case we shouldn't be here. |
| 340 bool ret = (answer_params.size() == 1U && !offer_params_.empty()); | 317 bool ret = (answer_params.size() == 1U && !offer_params_.empty()); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 } | 436 } |
| 460 | 437 |
| 461 /////////////////////////////////////////////////////////////////////////////// | 438 /////////////////////////////////////////////////////////////////////////////// |
| 462 // SrtpSession | 439 // SrtpSession |
| 463 | 440 |
| 464 bool SrtpSession::inited_ = false; | 441 bool SrtpSession::inited_ = false; |
| 465 | 442 |
| 466 // This lock protects SrtpSession::inited_. | 443 // This lock protects SrtpSession::inited_. |
| 467 rtc::GlobalLockPod SrtpSession::lock_; | 444 rtc::GlobalLockPod SrtpSession::lock_; |
| 468 | 445 |
| 469 SrtpSession::SrtpSession() : srtp_stat_(new SrtpStat()) { | 446 SrtpSession::SrtpSession() {} |
| 470 SignalSrtpError.repeat(srtp_stat_->SignalSrtpError); | |
| 471 } | |
| 472 | 447 |
| 473 SrtpSession::~SrtpSession() { | 448 SrtpSession::~SrtpSession() { |
| 474 if (session_) { | 449 if (session_) { |
| 475 srtp_set_user_data(session_, nullptr); | 450 srtp_set_user_data(session_, nullptr); |
| 476 srtp_dealloc(session_); | 451 srtp_dealloc(session_); |
| 477 } | 452 } |
| 478 } | 453 } |
| 479 | 454 |
| 480 bool SrtpSession::SetSend(int cs, const uint8_t* key, size_t len) { | 455 bool SrtpSession::SetSend(int cs, const uint8_t* key, size_t len) { |
| 481 return SetKey(ssrc_any_outbound, cs, key, len); | 456 return SetKey(ssrc_any_outbound, cs, key, len); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 494 | 469 |
| 495 int need_len = in_len + rtp_auth_tag_len_; // NOLINT | 470 int need_len = in_len + rtp_auth_tag_len_; // NOLINT |
| 496 if (max_len < need_len) { | 471 if (max_len < need_len) { |
| 497 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " | 472 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " |
| 498 << max_len << " is less than the needed " << need_len; | 473 << max_len << " is less than the needed " << need_len; |
| 499 return false; | 474 return false; |
| 500 } | 475 } |
| 501 | 476 |
| 502 *out_len = in_len; | 477 *out_len = in_len; |
| 503 int err = srtp_protect(session_, p, out_len); | 478 int err = srtp_protect(session_, p, out_len); |
| 504 uint32_t ssrc; | |
| 505 if (GetRtpSsrc(p, in_len, &ssrc)) { | |
| 506 srtp_stat_->AddProtectRtpResult(ssrc, err); | |
| 507 } | |
| 508 int seq_num; | 479 int seq_num; |
| 509 GetRtpSeqNum(p, in_len, &seq_num); | 480 GetRtpSeqNum(p, in_len, &seq_num); |
| 510 if (err != srtp_err_status_ok) { | 481 if (err != srtp_err_status_ok) { |
| 511 LOG(LS_WARNING) << "Failed to protect SRTP packet, seqnum=" | 482 LOG(LS_WARNING) << "Failed to protect SRTP packet, seqnum=" |
| 512 << seq_num << ", err=" << err << ", last seqnum=" | 483 << seq_num << ", err=" << err << ", last seqnum=" |
| 513 << last_send_seq_num_; | 484 << last_send_seq_num_; |
| 514 return false; | 485 return false; |
| 515 } | 486 } |
| 516 last_send_seq_num_ = seq_num; | 487 last_send_seq_num_ = seq_num; |
| 517 return true; | 488 return true; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 537 | 508 |
| 538 int need_len = in_len + sizeof(uint32_t) + rtcp_auth_tag_len_; // NOLINT | 509 int need_len = in_len + sizeof(uint32_t) + rtcp_auth_tag_len_; // NOLINT |
| 539 if (max_len < need_len) { | 510 if (max_len < need_len) { |
| 540 LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length " | 511 LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length " |
| 541 << max_len << " is less than the needed " << need_len; | 512 << max_len << " is less than the needed " << need_len; |
| 542 return false; | 513 return false; |
| 543 } | 514 } |
| 544 | 515 |
| 545 *out_len = in_len; | 516 *out_len = in_len; |
| 546 int err = srtp_protect_rtcp(session_, p, out_len); | 517 int err = srtp_protect_rtcp(session_, p, out_len); |
| 547 srtp_stat_->AddProtectRtcpResult(err); | |
| 548 if (err != srtp_err_status_ok) { | 518 if (err != srtp_err_status_ok) { |
| 549 LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; | 519 LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; |
| 550 return false; | 520 return false; |
| 551 } | 521 } |
| 552 return true; | 522 return true; |
| 553 } | 523 } |
| 554 | 524 |
| 555 bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { | 525 bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { |
| 556 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 526 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 557 if (!session_) { | 527 if (!session_) { |
| 558 LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session"; | 528 LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session"; |
| 559 return false; | 529 return false; |
| 560 } | 530 } |
| 561 | 531 |
| 562 *out_len = in_len; | 532 *out_len = in_len; |
| 563 int err = srtp_unprotect(session_, p, out_len); | 533 int err = srtp_unprotect(session_, p, out_len); |
| 564 uint32_t ssrc; | |
| 565 if (GetRtpSsrc(p, in_len, &ssrc)) { | |
| 566 srtp_stat_->AddUnprotectRtpResult(ssrc, err); | |
| 567 } | |
| 568 if (err != srtp_err_status_ok) { | 534 if (err != srtp_err_status_ok) { |
| 569 LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; | 535 LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; |
| 570 return false; | 536 return false; |
| 571 } | 537 } |
| 572 return true; | 538 return true; |
| 573 } | 539 } |
| 574 | 540 |
| 575 bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { | 541 bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { |
| 576 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 542 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 577 if (!session_) { | 543 if (!session_) { |
| 578 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session"; | 544 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session"; |
| 579 return false; | 545 return false; |
| 580 } | 546 } |
| 581 | 547 |
| 582 *out_len = in_len; | 548 *out_len = in_len; |
| 583 int err = srtp_unprotect_rtcp(session_, p, out_len); | 549 int err = srtp_unprotect_rtcp(session_, p, out_len); |
| 584 srtp_stat_->AddUnprotectRtcpResult(err); | |
| 585 if (err != srtp_err_status_ok) { | 550 if (err != srtp_err_status_ok) { |
| 586 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; | 551 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; |
| 587 return false; | 552 return false; |
| 588 } | 553 } |
| 589 return true; | 554 return true; |
| 590 } | 555 } |
| 591 | 556 |
| 592 bool SrtpSession::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { | 557 bool SrtpSession::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { |
| 593 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 558 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 594 RTC_DCHECK(IsExternalAuthActive()); | 559 RTC_DCHECK(IsExternalAuthActive()); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 return false; | 608 return false; |
| 644 } | 609 } |
| 645 | 610 |
| 646 // Shift packet index, put into network byte order | 611 // Shift packet index, put into network byte order |
| 647 *index = static_cast<int64_t>( | 612 *index = static_cast<int64_t>( |
| 648 rtc::NetworkToHost64( | 613 rtc::NetworkToHost64( |
| 649 srtp_rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); | 614 srtp_rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); |
| 650 return true; | 615 return true; |
| 651 } | 616 } |
| 652 | 617 |
| 653 void SrtpSession::set_signal_silent_time(int signal_silent_time_in_ms) { | |
| 654 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); | |
| 655 } | |
| 656 | |
| 657 bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) { | 618 bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) { |
| 658 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 619 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 659 if (session_) { | 620 if (session_) { |
| 660 LOG(LS_ERROR) << "Failed to create SRTP session: " | 621 LOG(LS_ERROR) << "Failed to create SRTP session: " |
| 661 << "SRTP session already created"; | 622 << "SRTP session already created"; |
| 662 return false; | 623 return false; |
| 663 } | 624 } |
| 664 | 625 |
| 665 if (!Init()) { | 626 if (!Init()) { |
| 666 return false; | 627 return false; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { | 761 void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { |
| 801 // Callback will be executed from same thread that calls the "srtp_protect" | 762 // Callback will be executed from same thread that calls the "srtp_protect" |
| 802 // and "srtp_unprotect" functions. | 763 // and "srtp_unprotect" functions. |
| 803 SrtpSession* session = static_cast<SrtpSession*>( | 764 SrtpSession* session = static_cast<SrtpSession*>( |
| 804 srtp_get_user_data(ev->session)); | 765 srtp_get_user_data(ev->session)); |
| 805 if (session) { | 766 if (session) { |
| 806 session->HandleEvent(ev); | 767 session->HandleEvent(ev); |
| 807 } | 768 } |
| 808 } | 769 } |
| 809 | 770 |
| 810 /////////////////////////////////////////////////////////////////////////////// | |
| 811 // SrtpStat | |
| 812 | |
| 813 SrtpStat::SrtpStat() | |
| 814 : signal_silent_time_(1000) { | |
| 815 } | |
| 816 | |
| 817 void SrtpStat::AddProtectRtpResult(uint32_t ssrc, int result) { | |
| 818 FailureKey key; | |
| 819 key.ssrc = ssrc; | |
| 820 key.mode = SrtpFilter::PROTECT; | |
| 821 switch (result) { | |
| 822 case srtp_err_status_ok: | |
| 823 key.error = SrtpFilter::ERROR_NONE; | |
| 824 break; | |
| 825 case srtp_err_status_auth_fail: | |
| 826 key.error = SrtpFilter::ERROR_AUTH; | |
| 827 break; | |
| 828 default: | |
| 829 key.error = SrtpFilter::ERROR_FAIL; | |
| 830 } | |
| 831 HandleSrtpResult(key); | |
| 832 } | |
| 833 | |
| 834 void SrtpStat::AddUnprotectRtpResult(uint32_t ssrc, int result) { | |
| 835 FailureKey key; | |
| 836 key.ssrc = ssrc; | |
| 837 key.mode = SrtpFilter::UNPROTECT; | |
| 838 switch (result) { | |
| 839 case srtp_err_status_ok: | |
| 840 key.error = SrtpFilter::ERROR_NONE; | |
| 841 break; | |
| 842 case srtp_err_status_auth_fail: | |
| 843 key.error = SrtpFilter::ERROR_AUTH; | |
| 844 break; | |
| 845 case srtp_err_status_replay_fail: | |
| 846 case srtp_err_status_replay_old: | |
| 847 key.error = SrtpFilter::ERROR_REPLAY; | |
| 848 break; | |
| 849 default: | |
| 850 key.error = SrtpFilter::ERROR_FAIL; | |
| 851 } | |
| 852 HandleSrtpResult(key); | |
| 853 } | |
| 854 | |
| 855 void SrtpStat::AddProtectRtcpResult(int result) { | |
| 856 AddProtectRtpResult(0U, result); | |
| 857 } | |
| 858 | |
| 859 void SrtpStat::AddUnprotectRtcpResult(int result) { | |
| 860 AddUnprotectRtpResult(0U, result); | |
| 861 } | |
| 862 | |
| 863 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { | |
| 864 // Handle some cases where error should be signalled right away. For other | |
| 865 // errors, trigger error for the first time seeing it. After that, silent | |
| 866 // the same error for a certain amount of time (default 1 sec). | |
| 867 if (key.error != SrtpFilter::ERROR_NONE) { | |
| 868 // For errors, signal first time and wait for 1 sec. | |
| 869 FailureStat* stat = &(failures_[key]); | |
| 870 int64_t current_time = rtc::TimeMillis(); | |
| 871 if (stat->last_signal_time == 0 || | |
| 872 rtc::TimeDiff(current_time, stat->last_signal_time) > | |
| 873 signal_silent_time_) { | |
| 874 SignalSrtpError(key.ssrc, key.mode, key.error); | |
| 875 stat->last_signal_time = current_time; | |
| 876 } | |
| 877 } | |
| 878 } | |
| 879 | |
| 880 } // namespace cricket | 771 } // namespace cricket |
| OLD | NEW |