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 |