Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: webrtc/pc/srtpfilter.cc

Issue 2761143002: Support encrypted RTP extensions (RFC 6904) (Closed)
Patch Set: Various changes based on feedback from Peter and Taylor. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 ContentSource source) { 59 ContentSource source) {
60 return DoSetAnswer(answer_params, source, true); 60 return DoSetAnswer(answer_params, source, true);
61 } 61 }
62 62
63 bool SrtpFilter::SetProvisionalAnswer( 63 bool SrtpFilter::SetProvisionalAnswer(
64 const std::vector<CryptoParams>& answer_params, 64 const std::vector<CryptoParams>& answer_params,
65 ContentSource source) { 65 ContentSource source) {
66 return DoSetAnswer(answer_params, source, false); 66 return DoSetAnswer(answer_params, source, false);
67 } 67 }
68 68
69 void SrtpFilter::GetSendRecvEncryptedHeaderExtensions(
70 std::vector<int>* send_extensions, std::vector<int>* recv_extensions) {
71 // Send local extension header encrypted if the remote also uses it
72 // encrypted and vice versa.
73 for (const webrtc::RtpExtension& extension :
74 local_encrypted_header_extensions_) {
75 if (webrtc::RtpExtension::FindHeaderExtensionByUri(
76 remote_encrypted_header_extensions_, extension.uri)) {
77 send_extensions->push_back(extension.id);
78 }
79 }
80 for (const webrtc::RtpExtension& extension :
81 remote_encrypted_header_extensions_) {
82 if (webrtc::RtpExtension::FindHeaderExtensionByUri(
83 local_encrypted_header_extensions_, extension.uri)) {
84 recv_extensions->push_back(extension.id);
85 }
86 }
87 }
88
69 bool SrtpFilter::SetRtpParams(int send_cs, 89 bool SrtpFilter::SetRtpParams(int send_cs,
70 const uint8_t* send_key, 90 const uint8_t* send_key,
71 int send_key_len, 91 int send_key_len,
72 int recv_cs, 92 int recv_cs,
73 const uint8_t* recv_key, 93 const uint8_t* recv_key,
74 int recv_key_len) { 94 int recv_key_len) {
75 if (IsActive()) { 95 if (IsActive()) {
76 LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active"; 96 LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active";
77 return false; 97 return false;
78 } 98 }
79 CreateSrtpSessions(); 99 CreateSrtpSessions();
80 if (!send_session_->SetSend(send_cs, send_key, send_key_len)) 100 std::vector<int> send_encrypted_header_extensions;
101 std::vector<int> recv_encrypted_header_extensions;
102
103 GetSendRecvEncryptedHeaderExtensions(&send_encrypted_header_extensions,
104 &recv_encrypted_header_extensions);
105 if (!send_session_->SetSend(send_cs, send_key, send_key_len,
106 send_encrypted_header_extensions)) {
81 return false; 107 return false;
108 }
82 109
83 if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) 110 if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len,
111 recv_encrypted_header_extensions)) {
84 return false; 112 return false;
113 }
85 114
86 state_ = ST_ACTIVE; 115 state_ = ST_ACTIVE;
87 116
88 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" 117 LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
89 << " send cipher_suite " << send_cs 118 << " send cipher_suite " << send_cs
90 << " recv cipher_suite " << recv_cs; 119 << " recv cipher_suite " << recv_cs;
91 return true; 120 return true;
92 } 121 }
93 122
94 // This function is provided separately because DTLS-SRTP behaves 123 // This function is provided separately because DTLS-SRTP behaves
(...skipping 10 matching lines...) Expand all
105 int recv_cs, 134 int recv_cs,
106 const uint8_t* recv_key, 135 const uint8_t* recv_key,
107 int recv_key_len) { 136 int recv_key_len) {
108 // This can only be called once, but can be safely called after 137 // This can only be called once, but can be safely called after
109 // SetRtpParams 138 // SetRtpParams
110 if (send_rtcp_session_ || recv_rtcp_session_) { 139 if (send_rtcp_session_ || recv_rtcp_session_) {
111 LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; 140 LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active";
112 return false; 141 return false;
113 } 142 }
114 143
144 // RTCP doesn't support header encryption.
145 std::vector<int> no_encrypted_header_extensions;
115 send_rtcp_session_.reset(new SrtpSession()); 146 send_rtcp_session_.reset(new SrtpSession());
116 SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError); 147 SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError);
117 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); 148 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)) 149 if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len,
150 no_encrypted_header_extensions)) {
119 return false; 151 return false;
152 }
120 153
121 recv_rtcp_session_.reset(new SrtpSession()); 154 recv_rtcp_session_.reset(new SrtpSession());
122 SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError); 155 SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError);
123 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); 156 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)) 157 if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len,
158 no_encrypted_header_extensions)) {
125 return false; 159 return false;
160 }
126 161
127 LOG(LS_INFO) << "SRTCP activated with negotiated parameters:" 162 LOG(LS_INFO) << "SRTCP activated with negotiated parameters:"
128 << " send cipher_suite " << send_cs 163 << " send cipher_suite " << send_cs
129 << " recv cipher_suite " << recv_cs; 164 << " recv cipher_suite " << recv_cs;
130 165
131 return true; 166 return true;
132 } 167 }
133 168
134 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { 169 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
135 if (!IsActive()) { 170 if (!IsActive()) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 send_session_->set_signal_silent_time(signal_silent_time_in_ms); 270 send_session_->set_signal_silent_time(signal_silent_time_in_ms);
236 RTC_CHECK(recv_session_); 271 RTC_CHECK(recv_session_);
237 recv_session_->set_signal_silent_time(signal_silent_time_in_ms); 272 recv_session_->set_signal_silent_time(signal_silent_time_in_ms);
238 if (send_rtcp_session_) 273 if (send_rtcp_session_)
239 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); 274 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms);
240 if (recv_rtcp_session_) 275 if (recv_rtcp_session_)
241 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); 276 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms);
242 } 277 }
243 } 278 }
244 279
280 void SrtpFilter::SetEncryptedHeaderExtensions(ContentSource source,
281 const std::vector<webrtc::RtpExtension>& extensions) {
Taylor Brandstetter 2017/03/23 20:10:56 The situation that's not being handled right now i
joachim 2017/03/30 22:43:49 This is now supported. Encrypted header extensions
282 if (source == CS_LOCAL) {
283 local_encrypted_header_extensions_ = extensions;
284 } else {
285 remote_encrypted_header_extensions_ = extensions;
286 }
287 }
288
245 bool SrtpFilter::ExpectOffer(ContentSource source) { 289 bool SrtpFilter::ExpectOffer(ContentSource source) {
246 return ((state_ == ST_INIT) || 290 return ((state_ == ST_INIT) ||
247 (state_ == ST_ACTIVE) || 291 (state_ == ST_ACTIVE) ||
248 (state_ == ST_SENTOFFER && source == CS_LOCAL) || 292 (state_ == ST_SENTOFFER && source == CS_LOCAL) ||
249 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || 293 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) ||
250 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || 294 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) ||
251 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); 295 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE));
252 } 296 }
253 297
254 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, 298 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params,
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 // TODO(juberti): Zero these buffers after use. 444 // TODO(juberti): Zero these buffers after use.
401 bool ret; 445 bool ret;
402 rtc::Buffer send_key(send_key_len + send_salt_len); 446 rtc::Buffer send_key(send_key_len + send_salt_len);
403 rtc::Buffer recv_key(recv_key_len + recv_salt_len); 447 rtc::Buffer recv_key(recv_key_len + recv_salt_len);
404 ret = (ParseKeyParams(send_params.key_params, send_key.data(), 448 ret = (ParseKeyParams(send_params.key_params, send_key.data(),
405 send_key.size()) && 449 send_key.size()) &&
406 ParseKeyParams(recv_params.key_params, recv_key.data(), 450 ParseKeyParams(recv_params.key_params, recv_key.data(),
407 recv_key.size())); 451 recv_key.size()));
408 if (ret) { 452 if (ret) {
409 CreateSrtpSessions(); 453 CreateSrtpSessions();
454 std::vector<int> send_encrypted_header_extensions;
455 std::vector<int> recv_encrypted_header_extensions;
456
457 GetSendRecvEncryptedHeaderExtensions(&send_encrypted_header_extensions,
458 &recv_encrypted_header_extensions);
410 ret = (send_session_->SetSend( 459 ret = (send_session_->SetSend(
411 rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), 460 rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite),
412 send_key.data(), send_key.size()) && 461 send_key.data(), send_key.size(),
462 send_encrypted_header_extensions) &&
413 recv_session_->SetRecv( 463 recv_session_->SetRecv(
414 rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), 464 rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite),
415 recv_key.data(), recv_key.size())); 465 recv_key.data(), recv_key.size(),
466 recv_encrypted_header_extensions));
416 } 467 }
417 if (ret) { 468 if (ret) {
418 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" 469 LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
419 << " send cipher_suite " << send_params.cipher_suite 470 << " send cipher_suite " << send_params.cipher_suite
420 << " recv cipher_suite " << recv_params.cipher_suite; 471 << " recv cipher_suite " << recv_params.cipher_suite;
421 applied_send_params_ = send_params; 472 applied_send_params_ = send_params;
422 applied_recv_params_ = recv_params; 473 applied_recv_params_ = recv_params;
423 } else { 474 } else {
424 LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; 475 LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters";
425 } 476 }
426 return ret; 477 return ret;
427 } 478 }
428 479
429 bool SrtpFilter::ResetParams() { 480 bool SrtpFilter::ResetParams() {
430 offer_params_.clear(); 481 offer_params_.clear();
431 state_ = ST_INIT; 482 state_ = ST_INIT;
432 send_session_ = nullptr; 483 send_session_ = nullptr;
433 recv_session_ = nullptr; 484 recv_session_ = nullptr;
434 send_rtcp_session_ = nullptr; 485 send_rtcp_session_ = nullptr;
435 recv_rtcp_session_ = nullptr; 486 recv_rtcp_session_ = nullptr;
487 local_encrypted_header_extensions_.clear();
488 remote_encrypted_header_extensions_.clear();
436 LOG(LS_INFO) << "SRTP reset to init state"; 489 LOG(LS_INFO) << "SRTP reset to init state";
437 return true; 490 return true;
438 } 491 }
439 492
440 bool SrtpFilter::ParseKeyParams(const std::string& key_params, 493 bool SrtpFilter::ParseKeyParams(const std::string& key_params,
441 uint8_t* key, 494 uint8_t* key,
442 size_t len) { 495 size_t len) {
443 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" 496 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2"
444 497
445 // Fail if key-method is wrong. 498 // Fail if key-method is wrong.
(...skipping 24 matching lines...) Expand all
470 SignalSrtpError.repeat(srtp_stat_->SignalSrtpError); 523 SignalSrtpError.repeat(srtp_stat_->SignalSrtpError);
471 } 524 }
472 525
473 SrtpSession::~SrtpSession() { 526 SrtpSession::~SrtpSession() {
474 if (session_) { 527 if (session_) {
475 srtp_set_user_data(session_, nullptr); 528 srtp_set_user_data(session_, nullptr);
476 srtp_dealloc(session_); 529 srtp_dealloc(session_);
477 } 530 }
478 } 531 }
479 532
480 bool SrtpSession::SetSend(int cs, const uint8_t* key, size_t len) { 533 bool SrtpSession::SetSend(int cs, const uint8_t* key, size_t len,
481 return SetKey(ssrc_any_outbound, cs, key, len); 534 const std::vector<int>& encrypted_header_extensions) {
535 return SetKeyAndEncryptedHeaderExtensions(ssrc_any_outbound, cs, key, len,
536 encrypted_header_extensions);
482 } 537 }
483 538
484 bool SrtpSession::SetRecv(int cs, const uint8_t* key, size_t len) { 539 bool SrtpSession::SetRecv(int cs, const uint8_t* key, size_t len,
485 return SetKey(ssrc_any_inbound, cs, key, len); 540 const std::vector<int>& encrypted_header_extensions) {
541 return SetKeyAndEncryptedHeaderExtensions(ssrc_any_inbound, cs, key, len,
542 encrypted_header_extensions);
486 } 543 }
487 544
488 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { 545 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
489 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 546 RTC_DCHECK(thread_checker_.CalledOnValidThread());
490 if (!session_) { 547 if (!session_) {
491 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; 548 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session";
492 return false; 549 return false;
493 } 550 }
494 551
495 int need_len = in_len + rtp_auth_tag_len_; // NOLINT 552 int need_len = in_len + rtp_auth_tag_len_; // NOLINT
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 *index = static_cast<int64_t>( 704 *index = static_cast<int64_t>(
648 rtc::NetworkToHost64( 705 rtc::NetworkToHost64(
649 srtp_rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); 706 srtp_rdbx_get_packet_index(&stream->rtp_rdbx) << 16));
650 return true; 707 return true;
651 } 708 }
652 709
653 void SrtpSession::set_signal_silent_time(int signal_silent_time_in_ms) { 710 void SrtpSession::set_signal_silent_time(int signal_silent_time_in_ms) {
654 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); 711 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms);
655 } 712 }
656 713
657 bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) { 714 bool SrtpSession::SetKeyAndEncryptedHeaderExtensions(int type, int cs,
715 const uint8_t* key, size_t len,
716 const std::vector<int>& encrypted_header_extensions) {
658 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 717 RTC_DCHECK(thread_checker_.CalledOnValidThread());
659 if (session_) { 718 if (session_) {
660 LOG(LS_ERROR) << "Failed to create SRTP session: " 719 LOG(LS_ERROR) << "Failed to create SRTP session: "
661 << "SRTP session already created"; 720 << "SRTP session already created";
662 return false; 721 return false;
663 } 722 }
664 723
665 if (!Init()) { 724 if (!Init()) {
666 return false; 725 return false;
667 } 726 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 // If external authentication option is enabled, supply custom auth module 771 // If external authentication option is enabled, supply custom auth module
713 // id EXTERNAL_HMAC_SHA1 in the policy structure. 772 // id EXTERNAL_HMAC_SHA1 in the policy structure.
714 // We want to set this option only for rtp packets. 773 // We want to set this option only for rtp packets.
715 // By default policy structure is initialized to HMAC_SHA1. 774 // By default policy structure is initialized to HMAC_SHA1.
716 // Enable external HMAC authentication only for outgoing streams and only 775 // Enable external HMAC authentication only for outgoing streams and only
717 // for cipher suites that support it (i.e. only non-GCM cipher suites). 776 // for cipher suites that support it (i.e. only non-GCM cipher suites).
718 if (type == ssrc_any_outbound && IsExternalAuthEnabled() && 777 if (type == ssrc_any_outbound && IsExternalAuthEnabled() &&
719 !rtc::IsGcmCryptoSuite(cs)) { 778 !rtc::IsGcmCryptoSuite(cs)) {
720 policy.rtp.auth_type = EXTERNAL_HMAC_SHA1; 779 policy.rtp.auth_type = EXTERNAL_HMAC_SHA1;
721 } 780 }
781 if (!encrypted_header_extensions.empty()) {
782 policy.enc_xtn_hdr = const_cast<int*>(&encrypted_header_extensions[0]);
783 policy.enc_xtn_hdr_count = encrypted_header_extensions.size();
784 }
722 policy.next = nullptr; 785 policy.next = nullptr;
723 786
724 int err = srtp_create(&session_, &policy); 787 int err = srtp_create(&session_, &policy);
725 if (err != srtp_err_status_ok) { 788 if (err != srtp_err_status_ok) {
726 session_ = nullptr; 789 session_ = nullptr;
727 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; 790 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err;
728 return false; 791 return false;
729 } 792 }
730 793
731 srtp_set_user_data(session_, this); 794 srtp_set_user_data(session_, this);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 if (stat->last_signal_time == 0 || 934 if (stat->last_signal_time == 0 ||
872 rtc::TimeDiff(current_time, stat->last_signal_time) > 935 rtc::TimeDiff(current_time, stat->last_signal_time) >
873 signal_silent_time_) { 936 signal_silent_time_) {
874 SignalSrtpError(key.ssrc, key.mode, key.error); 937 SignalSrtpError(key.ssrc, key.mode, key.error);
875 stat->last_signal_time = current_time; 938 stat->last_signal_time = current_time;
876 } 939 }
877 } 940 }
878 } 941 }
879 942
880 } // namespace cricket 943 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698