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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |