| 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 |
| 11 #include "webrtc/pc/srtpfilter.h" | 11 #include "webrtc/pc/srtpfilter.h" |
| 12 | 12 |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 | 14 |
| 15 #include <algorithm> | 15 #include <algorithm> |
| 16 | 16 |
| 17 #include "webrtc/base/base64.h" | 17 #include "webrtc/base/base64.h" |
| 18 #include "webrtc/base/byteorder.h" | 18 #include "webrtc/base/byteorder.h" |
| 19 #include "webrtc/base/checks.h" |
| 19 #include "webrtc/base/common.h" | 20 #include "webrtc/base/common.h" |
| 20 #include "webrtc/base/logging.h" | 21 #include "webrtc/base/logging.h" |
| 21 #include "webrtc/base/stringencode.h" | 22 #include "webrtc/base/stringencode.h" |
| 22 #include "webrtc/base/timeutils.h" | 23 #include "webrtc/base/timeutils.h" |
| 23 #include "webrtc/media/base/rtputils.h" | 24 #include "webrtc/media/base/rtputils.h" |
| 24 | 25 |
| 25 // Enable this line to turn on SRTP debugging | 26 // Enable this line to turn on SRTP debugging |
| 26 // #define SRTP_DEBUG | 27 // #define SRTP_DEBUG |
| 27 | 28 |
| 28 #ifdef HAVE_SRTP | 29 #ifdef HAVE_SRTP |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 << " recv cipher_suite " << recv_cs; | 191 << " recv cipher_suite " << recv_cs; |
| 191 | 192 |
| 192 return true; | 193 return true; |
| 193 } | 194 } |
| 194 | 195 |
| 195 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { | 196 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { |
| 196 if (!IsActive()) { | 197 if (!IsActive()) { |
| 197 LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; | 198 LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; |
| 198 return false; | 199 return false; |
| 199 } | 200 } |
| 200 ASSERT(send_session_ != NULL); | 201 RTC_CHECK(send_session_); |
| 201 return send_session_->ProtectRtp(p, in_len, max_len, out_len); | 202 return send_session_->ProtectRtp(p, in_len, max_len, out_len); |
| 202 } | 203 } |
| 203 | 204 |
| 204 bool SrtpFilter::ProtectRtp(void* p, | 205 bool SrtpFilter::ProtectRtp(void* p, |
| 205 int in_len, | 206 int in_len, |
| 206 int max_len, | 207 int max_len, |
| 207 int* out_len, | 208 int* out_len, |
| 208 int64_t* index) { | 209 int64_t* index) { |
| 209 if (!IsActive()) { | 210 if (!IsActive()) { |
| 210 LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; | 211 LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; |
| 211 return false; | 212 return false; |
| 212 } | 213 } |
| 213 ASSERT(send_session_ != NULL); | 214 RTC_CHECK(send_session_); |
| 214 return send_session_->ProtectRtp(p, in_len, max_len, out_len, index); | 215 return send_session_->ProtectRtp(p, in_len, max_len, out_len, index); |
| 215 } | 216 } |
| 216 | 217 |
| 217 bool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { | 218 bool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { |
| 218 if (!IsActive()) { | 219 if (!IsActive()) { |
| 219 LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active"; | 220 LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active"; |
| 220 return false; | 221 return false; |
| 221 } | 222 } |
| 222 if (send_rtcp_session_) { | 223 if (send_rtcp_session_) { |
| 223 return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len); | 224 return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len); |
| 224 } else { | 225 } else { |
| 225 ASSERT(send_session_ != NULL); | 226 RTC_CHECK(send_session_); |
| 226 return send_session_->ProtectRtcp(p, in_len, max_len, out_len); | 227 return send_session_->ProtectRtcp(p, in_len, max_len, out_len); |
| 227 } | 228 } |
| 228 } | 229 } |
| 229 | 230 |
| 230 bool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) { | 231 bool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) { |
| 231 if (!IsActive()) { | 232 if (!IsActive()) { |
| 232 LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active"; | 233 LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active"; |
| 233 return false; | 234 return false; |
| 234 } | 235 } |
| 235 ASSERT(recv_session_ != NULL); | 236 RTC_CHECK(recv_session_); |
| 236 return recv_session_->UnprotectRtp(p, in_len, out_len); | 237 return recv_session_->UnprotectRtp(p, in_len, out_len); |
| 237 } | 238 } |
| 238 | 239 |
| 239 bool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) { | 240 bool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) { |
| 240 if (!IsActive()) { | 241 if (!IsActive()) { |
| 241 LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active"; | 242 LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active"; |
| 242 return false; | 243 return false; |
| 243 } | 244 } |
| 244 if (recv_rtcp_session_) { | 245 if (recv_rtcp_session_) { |
| 245 return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len); | 246 return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len); |
| 246 } else { | 247 } else { |
| 247 ASSERT(recv_session_ != NULL); | 248 RTC_CHECK(recv_session_); |
| 248 return recv_session_->UnprotectRtcp(p, in_len, out_len); | 249 return recv_session_->UnprotectRtcp(p, in_len, out_len); |
| 249 } | 250 } |
| 250 } | 251 } |
| 251 | 252 |
| 252 bool SrtpFilter::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { | 253 bool SrtpFilter::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { |
| 253 if (!IsActive()) { | 254 if (!IsActive()) { |
| 254 LOG(LS_WARNING) << "Failed to GetRtpAuthParams: SRTP not active"; | 255 LOG(LS_WARNING) << "Failed to GetRtpAuthParams: SRTP not active"; |
| 255 return false; | 256 return false; |
| 256 } | 257 } |
| 257 | 258 |
| 258 ASSERT(send_session_ != NULL); | 259 RTC_CHECK(send_session_); |
| 259 return send_session_->GetRtpAuthParams(key, key_len, tag_len); | 260 return send_session_->GetRtpAuthParams(key, key_len, tag_len); |
| 260 } | 261 } |
| 261 | 262 |
| 262 void SrtpFilter::set_signal_silent_time(int signal_silent_time_in_ms) { | 263 void SrtpFilter::set_signal_silent_time(int signal_silent_time_in_ms) { |
| 263 signal_silent_time_in_ms_ = signal_silent_time_in_ms; | 264 signal_silent_time_in_ms_ = signal_silent_time_in_ms; |
| 264 if (IsActive()) { | 265 if (IsActive()) { |
| 265 ASSERT(send_session_ != NULL); | 266 RTC_CHECK(send_session_); |
| 266 send_session_->set_signal_silent_time(signal_silent_time_in_ms); | 267 send_session_->set_signal_silent_time(signal_silent_time_in_ms); |
| 267 ASSERT(recv_session_ != NULL); | 268 RTC_CHECK(recv_session_); |
| 268 recv_session_->set_signal_silent_time(signal_silent_time_in_ms); | 269 recv_session_->set_signal_silent_time(signal_silent_time_in_ms); |
| 269 if (send_rtcp_session_) | 270 if (send_rtcp_session_) |
| 270 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); | 271 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); |
| 271 if (recv_rtcp_session_) | 272 if (recv_rtcp_session_) |
| 272 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); | 273 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); |
| 273 } | 274 } |
| 274 } | 275 } |
| 275 | 276 |
| 276 bool SrtpFilter::ExpectOffer(ContentSource source) { | 277 bool SrtpFilter::ExpectOffer(ContentSource source) { |
| 277 return ((state_ == ST_INIT) || | 278 return ((state_ == ST_INIT) || |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" | 446 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" |
| 446 | 447 |
| 447 // Fail if key-method is wrong. | 448 // Fail if key-method is wrong. |
| 448 if (key_params.find("inline:") != 0) { | 449 if (key_params.find("inline:") != 0) { |
| 449 return false; | 450 return false; |
| 450 } | 451 } |
| 451 | 452 |
| 452 // Fail if base64 decode fails, or the key is the wrong size. | 453 // Fail if base64 decode fails, or the key is the wrong size. |
| 453 std::string key_b64(key_params.substr(7)), key_str; | 454 std::string key_b64(key_params.substr(7)), key_str; |
| 454 if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, | 455 if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, |
| 455 &key_str, NULL) || | 456 &key_str, nullptr) || |
| 456 static_cast<int>(key_str.size()) != len) { | 457 static_cast<int>(key_str.size()) != len) { |
| 457 return false; | 458 return false; |
| 458 } | 459 } |
| 459 | 460 |
| 460 memcpy(key, key_str.c_str(), len); | 461 memcpy(key, key_str.c_str(), len); |
| 461 return true; | 462 return true; |
| 462 } | 463 } |
| 463 | 464 |
| 464 /////////////////////////////////////////////////////////////////////////////// | 465 /////////////////////////////////////////////////////////////////////////////// |
| 465 // SrtpSession | 466 // SrtpSession |
| 466 | 467 |
| 467 #ifdef HAVE_SRTP | 468 #ifdef HAVE_SRTP |
| 468 | 469 |
| 469 bool SrtpSession::inited_ = false; | 470 bool SrtpSession::inited_ = false; |
| 470 | 471 |
| 471 // This lock protects SrtpSession::inited_ and SrtpSession::sessions_. | 472 // This lock protects SrtpSession::inited_. |
| 472 rtc::GlobalLockPod SrtpSession::lock_; | 473 rtc::GlobalLockPod SrtpSession::lock_; |
| 473 | 474 |
| 474 SrtpSession::SrtpSession() | 475 SrtpSession::SrtpSession() |
| 475 : session_(NULL), | 476 : session_(nullptr), |
| 476 rtp_auth_tag_len_(0), | 477 rtp_auth_tag_len_(0), |
| 477 rtcp_auth_tag_len_(0), | 478 rtcp_auth_tag_len_(0), |
| 478 srtp_stat_(new SrtpStat()), | 479 srtp_stat_(new SrtpStat()), |
| 479 last_send_seq_num_(-1) { | 480 last_send_seq_num_(-1) { |
| 480 { | |
| 481 rtc::GlobalLockScope ls(&lock_); | |
| 482 sessions()->push_back(this); | |
| 483 } | |
| 484 SignalSrtpError.repeat(srtp_stat_->SignalSrtpError); | 481 SignalSrtpError.repeat(srtp_stat_->SignalSrtpError); |
| 485 } | 482 } |
| 486 | 483 |
| 487 SrtpSession::~SrtpSession() { | 484 SrtpSession::~SrtpSession() { |
| 488 { | |
| 489 rtc::GlobalLockScope ls(&lock_); | |
| 490 sessions()->erase(std::find(sessions()->begin(), sessions()->end(), this)); | |
| 491 } | |
| 492 if (session_) { | 485 if (session_) { |
| 486 srtp_set_user_data(session_, nullptr); |
| 493 srtp_dealloc(session_); | 487 srtp_dealloc(session_); |
| 494 } | 488 } |
| 495 } | 489 } |
| 496 | 490 |
| 497 bool SrtpSession::SetSend(int cs, const uint8_t* key, int len) { | 491 bool SrtpSession::SetSend(int cs, const uint8_t* key, int len) { |
| 498 return SetKey(ssrc_any_outbound, cs, key, len); | 492 return SetKey(ssrc_any_outbound, cs, key, len); |
| 499 } | 493 } |
| 500 | 494 |
| 501 bool SrtpSession::SetRecv(int cs, const uint8_t* key, int len) { | 495 bool SrtpSession::SetRecv(int cs, const uint8_t* key, int len) { |
| 502 return SetKey(ssrc_any_inbound, cs, key, len); | 496 return SetKey(ssrc_any_inbound, cs, key, len); |
| 503 } | 497 } |
| 504 | 498 |
| 505 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { | 499 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { |
| 500 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 506 if (!session_) { | 501 if (!session_) { |
| 507 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; | 502 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; |
| 508 return false; | 503 return false; |
| 509 } | 504 } |
| 510 | 505 |
| 511 int need_len = in_len + rtp_auth_tag_len_; // NOLINT | 506 int need_len = in_len + rtp_auth_tag_len_; // NOLINT |
| 512 if (max_len < need_len) { | 507 if (max_len < need_len) { |
| 513 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " | 508 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " |
| 514 << max_len << " is less than the needed " << need_len; | 509 << max_len << " is less than the needed " << need_len; |
| 515 return false; | 510 return false; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 538 int max_len, | 533 int max_len, |
| 539 int* out_len, | 534 int* out_len, |
| 540 int64_t* index) { | 535 int64_t* index) { |
| 541 if (!ProtectRtp(p, in_len, max_len, out_len)) { | 536 if (!ProtectRtp(p, in_len, max_len, out_len)) { |
| 542 return false; | 537 return false; |
| 543 } | 538 } |
| 544 return (index) ? GetSendStreamPacketIndex(p, in_len, index) : true; | 539 return (index) ? GetSendStreamPacketIndex(p, in_len, index) : true; |
| 545 } | 540 } |
| 546 | 541 |
| 547 bool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { | 542 bool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { |
| 543 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 548 if (!session_) { | 544 if (!session_) { |
| 549 LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session"; | 545 LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session"; |
| 550 return false; | 546 return false; |
| 551 } | 547 } |
| 552 | 548 |
| 553 int need_len = in_len + sizeof(uint32_t) + rtcp_auth_tag_len_; // NOLINT | 549 int need_len = in_len + sizeof(uint32_t) + rtcp_auth_tag_len_; // NOLINT |
| 554 if (max_len < need_len) { | 550 if (max_len < need_len) { |
| 555 LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length " | 551 LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length " |
| 556 << max_len << " is less than the needed " << need_len; | 552 << max_len << " is less than the needed " << need_len; |
| 557 return false; | 553 return false; |
| 558 } | 554 } |
| 559 | 555 |
| 560 *out_len = in_len; | 556 *out_len = in_len; |
| 561 int err = srtp_protect_rtcp(session_, p, out_len); | 557 int err = srtp_protect_rtcp(session_, p, out_len); |
| 562 srtp_stat_->AddProtectRtcpResult(err); | 558 srtp_stat_->AddProtectRtcpResult(err); |
| 563 if (err != err_status_ok) { | 559 if (err != err_status_ok) { |
| 564 LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; | 560 LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; |
| 565 return false; | 561 return false; |
| 566 } | 562 } |
| 567 return true; | 563 return true; |
| 568 } | 564 } |
| 569 | 565 |
| 570 bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { | 566 bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { |
| 567 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 571 if (!session_) { | 568 if (!session_) { |
| 572 LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session"; | 569 LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session"; |
| 573 return false; | 570 return false; |
| 574 } | 571 } |
| 575 | 572 |
| 576 *out_len = in_len; | 573 *out_len = in_len; |
| 577 int err = srtp_unprotect(session_, p, out_len); | 574 int err = srtp_unprotect(session_, p, out_len); |
| 578 uint32_t ssrc; | 575 uint32_t ssrc; |
| 579 if (GetRtpSsrc(p, in_len, &ssrc)) { | 576 if (GetRtpSsrc(p, in_len, &ssrc)) { |
| 580 srtp_stat_->AddUnprotectRtpResult(ssrc, err); | 577 srtp_stat_->AddUnprotectRtpResult(ssrc, err); |
| 581 } | 578 } |
| 582 if (err != err_status_ok) { | 579 if (err != err_status_ok) { |
| 583 LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; | 580 LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; |
| 584 return false; | 581 return false; |
| 585 } | 582 } |
| 586 return true; | 583 return true; |
| 587 } | 584 } |
| 588 | 585 |
| 589 bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { | 586 bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { |
| 587 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 590 if (!session_) { | 588 if (!session_) { |
| 591 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session"; | 589 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session"; |
| 592 return false; | 590 return false; |
| 593 } | 591 } |
| 594 | 592 |
| 595 *out_len = in_len; | 593 *out_len = in_len; |
| 596 int err = srtp_unprotect_rtcp(session_, p, out_len); | 594 int err = srtp_unprotect_rtcp(session_, p, out_len); |
| 597 srtp_stat_->AddUnprotectRtcpResult(err); | 595 srtp_stat_->AddUnprotectRtcpResult(err); |
| 598 if (err != err_status_ok) { | 596 if (err != err_status_ok) { |
| 599 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; | 597 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; |
| 600 return false; | 598 return false; |
| 601 } | 599 } |
| 602 return true; | 600 return true; |
| 603 } | 601 } |
| 604 | 602 |
| 605 bool SrtpSession::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { | 603 bool SrtpSession::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { |
| 606 #if defined(ENABLE_EXTERNAL_AUTH) | 604 #if defined(ENABLE_EXTERNAL_AUTH) |
| 607 ExternalHmacContext* external_hmac = NULL; | 605 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 606 ExternalHmacContext* external_hmac = nullptr; |
| 608 // stream_template will be the reference context for other streams. | 607 // stream_template will be the reference context for other streams. |
| 609 // Let's use it for getting the keys. | 608 // Let's use it for getting the keys. |
| 610 srtp_stream_ctx_t* srtp_context = session_->stream_template; | 609 srtp_stream_ctx_t* srtp_context = session_->stream_template; |
| 611 if (srtp_context && srtp_context->rtp_auth) { | 610 if (srtp_context && srtp_context->rtp_auth) { |
| 612 external_hmac = reinterpret_cast<ExternalHmacContext*>( | 611 external_hmac = reinterpret_cast<ExternalHmacContext*>( |
| 613 srtp_context->rtp_auth->state); | 612 srtp_context->rtp_auth->state); |
| 614 } | 613 } |
| 615 | 614 |
| 616 if (!external_hmac) { | 615 if (!external_hmac) { |
| 617 LOG(LS_ERROR) << "Failed to get auth keys from libsrtp!."; | 616 LOG(LS_ERROR) << "Failed to get auth keys from libsrtp!."; |
| 618 return false; | 617 return false; |
| 619 } | 618 } |
| 620 | 619 |
| 621 *key = external_hmac->key; | 620 *key = external_hmac->key; |
| 622 *key_len = external_hmac->key_length; | 621 *key_len = external_hmac->key_length; |
| 623 *tag_len = rtp_auth_tag_len_; | 622 *tag_len = rtp_auth_tag_len_; |
| 624 return true; | 623 return true; |
| 625 #else | 624 #else |
| 626 return false; | 625 return false; |
| 627 #endif | 626 #endif |
| 628 } | 627 } |
| 629 | 628 |
| 630 bool SrtpSession::GetSendStreamPacketIndex(void* p, | 629 bool SrtpSession::GetSendStreamPacketIndex(void* p, |
| 631 int in_len, | 630 int in_len, |
| 632 int64_t* index) { | 631 int64_t* index) { |
| 632 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 633 srtp_hdr_t* hdr = reinterpret_cast<srtp_hdr_t*>(p); | 633 srtp_hdr_t* hdr = reinterpret_cast<srtp_hdr_t*>(p); |
| 634 srtp_stream_ctx_t* stream = srtp_get_stream(session_, hdr->ssrc); | 634 srtp_stream_ctx_t* stream = srtp_get_stream(session_, hdr->ssrc); |
| 635 if (stream == NULL) | 635 if (!stream) { |
| 636 return false; | 636 return false; |
| 637 } |
| 637 | 638 |
| 638 // Shift packet index, put into network byte order | 639 // Shift packet index, put into network byte order |
| 639 *index = static_cast<int64_t>( | 640 *index = static_cast<int64_t>( |
| 640 rtc::NetworkToHost64(rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); | 641 rtc::NetworkToHost64(rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); |
| 641 return true; | 642 return true; |
| 642 } | 643 } |
| 643 | 644 |
| 644 void SrtpSession::set_signal_silent_time(int signal_silent_time_in_ms) { | 645 void SrtpSession::set_signal_silent_time(int signal_silent_time_in_ms) { |
| 645 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); | 646 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); |
| 646 } | 647 } |
| 647 | 648 |
| 648 bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, int len) { | 649 bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, int len) { |
| 650 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 649 if (session_) { | 651 if (session_) { |
| 650 LOG(LS_ERROR) << "Failed to create SRTP session: " | 652 LOG(LS_ERROR) << "Failed to create SRTP session: " |
| 651 << "SRTP session already created"; | 653 << "SRTP session already created"; |
| 652 return false; | 654 return false; |
| 653 } | 655 } |
| 654 | 656 |
| 655 if (!Init()) { | 657 if (!Init()) { |
| 656 return false; | 658 return false; |
| 657 } | 659 } |
| 658 | 660 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 685 // If external authentication option is enabled, supply custom auth module | 687 // If external authentication option is enabled, supply custom auth module |
| 686 // id EXTERNAL_HMAC_SHA1 in the policy structure. | 688 // id EXTERNAL_HMAC_SHA1 in the policy structure. |
| 687 // We want to set this option only for rtp packets. | 689 // We want to set this option only for rtp packets. |
| 688 // By default policy structure is initialized to HMAC_SHA1. | 690 // By default policy structure is initialized to HMAC_SHA1. |
| 689 #if defined(ENABLE_EXTERNAL_AUTH) | 691 #if defined(ENABLE_EXTERNAL_AUTH) |
| 690 // Enable external HMAC authentication only for outgoing streams. | 692 // Enable external HMAC authentication only for outgoing streams. |
| 691 if (type == ssrc_any_outbound) { | 693 if (type == ssrc_any_outbound) { |
| 692 policy.rtp.auth_type = EXTERNAL_HMAC_SHA1; | 694 policy.rtp.auth_type = EXTERNAL_HMAC_SHA1; |
| 693 } | 695 } |
| 694 #endif | 696 #endif |
| 695 policy.next = NULL; | 697 policy.next = nullptr; |
| 696 | 698 |
| 697 int err = srtp_create(&session_, &policy); | 699 int err = srtp_create(&session_, &policy); |
| 698 if (err != err_status_ok) { | 700 if (err != err_status_ok) { |
| 699 session_ = NULL; | 701 session_ = nullptr; |
| 700 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; | 702 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; |
| 701 return false; | 703 return false; |
| 702 } | 704 } |
| 703 | 705 |
| 704 | 706 srtp_set_user_data(session_, this); |
| 705 rtp_auth_tag_len_ = policy.rtp.auth_tag_len; | 707 rtp_auth_tag_len_ = policy.rtp.auth_tag_len; |
| 706 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; | 708 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; |
| 707 return true; | 709 return true; |
| 708 } | 710 } |
| 709 | 711 |
| 710 bool SrtpSession::Init() { | 712 bool SrtpSession::Init() { |
| 711 rtc::GlobalLockScope ls(&lock_); | 713 rtc::GlobalLockScope ls(&lock_); |
| 712 | 714 |
| 713 if (!inited_) { | 715 if (!inited_) { |
| 714 int err; | 716 int err; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 743 int err = srtp_shutdown(); | 745 int err = srtp_shutdown(); |
| 744 if (err) { | 746 if (err) { |
| 745 LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err; | 747 LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err; |
| 746 return; | 748 return; |
| 747 } | 749 } |
| 748 inited_ = false; | 750 inited_ = false; |
| 749 } | 751 } |
| 750 } | 752 } |
| 751 | 753 |
| 752 void SrtpSession::HandleEvent(const srtp_event_data_t* ev) { | 754 void SrtpSession::HandleEvent(const srtp_event_data_t* ev) { |
| 755 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 753 switch (ev->event) { | 756 switch (ev->event) { |
| 754 case event_ssrc_collision: | 757 case event_ssrc_collision: |
| 755 LOG(LS_INFO) << "SRTP event: SSRC collision"; | 758 LOG(LS_INFO) << "SRTP event: SSRC collision"; |
| 756 break; | 759 break; |
| 757 case event_key_soft_limit: | 760 case event_key_soft_limit: |
| 758 LOG(LS_INFO) << "SRTP event: reached soft key usage limit"; | 761 LOG(LS_INFO) << "SRTP event: reached soft key usage limit"; |
| 759 break; | 762 break; |
| 760 case event_key_hard_limit: | 763 case event_key_hard_limit: |
| 761 LOG(LS_INFO) << "SRTP event: reached hard key usage limit"; | 764 LOG(LS_INFO) << "SRTP event: reached hard key usage limit"; |
| 762 break; | 765 break; |
| 763 case event_packet_index_limit: | 766 case event_packet_index_limit: |
| 764 LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)"; | 767 LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)"; |
| 765 break; | 768 break; |
| 766 default: | 769 default: |
| 767 LOG(LS_INFO) << "SRTP event: unknown " << ev->event; | 770 LOG(LS_INFO) << "SRTP event: unknown " << ev->event; |
| 768 break; | 771 break; |
| 769 } | 772 } |
| 770 } | 773 } |
| 771 | 774 |
| 772 void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { | 775 void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { |
| 773 rtc::GlobalLockScope ls(&lock_); | 776 // Callback will be executed from same thread that calls the "srtp_protect" |
| 774 | 777 // and "srtp_unprotect" functions. |
| 775 for (std::list<SrtpSession*>::iterator it = sessions()->begin(); | 778 SrtpSession* session = static_cast<SrtpSession*>( |
| 776 it != sessions()->end(); ++it) { | 779 srtp_get_user_data(ev->session)); |
| 777 if ((*it)->session_ == ev->session) { | 780 if (session) { |
| 778 (*it)->HandleEvent(ev); | 781 session->HandleEvent(ev); |
| 779 break; | |
| 780 } | |
| 781 } | 782 } |
| 782 } | 783 } |
| 783 | 784 |
| 784 std::list<SrtpSession*>* SrtpSession::sessions() { | |
| 785 RTC_DEFINE_STATIC_LOCAL(std::list<SrtpSession*>, sessions, ()); | |
| 786 return &sessions; | |
| 787 } | |
| 788 | |
| 789 #else // !HAVE_SRTP | 785 #else // !HAVE_SRTP |
| 790 | 786 |
| 791 // On some systems, SRTP is not (yet) available. | 787 // On some systems, SRTP is not (yet) available. |
| 792 | 788 |
| 793 SrtpSession::SrtpSession() { | 789 SrtpSession::SrtpSession() { |
| 794 LOG(WARNING) << "SRTP implementation is missing."; | 790 LOG(WARNING) << "SRTP implementation is missing."; |
| 795 } | 791 } |
| 796 | 792 |
| 797 SrtpSession::~SrtpSession() { | 793 SrtpSession::~SrtpSession() { |
| 798 } | 794 } |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 SrtpNotAvailable(__FUNCTION__); | 922 SrtpNotAvailable(__FUNCTION__); |
| 927 } | 923 } |
| 928 | 924 |
| 929 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { | 925 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { |
| 930 SrtpNotAvailable(__FUNCTION__); | 926 SrtpNotAvailable(__FUNCTION__); |
| 931 } | 927 } |
| 932 | 928 |
| 933 #endif // HAVE_SRTP | 929 #endif // HAVE_SRTP |
| 934 | 930 |
| 935 } // namespace cricket | 931 } // namespace cricket |
| OLD | NEW |