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. The extension ids could be different for local |
| 73 // and remote, so we need to intersect twice. |
| 74 for (const webrtc::RtpExtension& extension : |
| 75 local_encrypted_header_extensions_) { |
| 76 if (webrtc::RtpExtension::FindHeaderExtensionByUri( |
| 77 remote_encrypted_header_extensions_, extension.uri)) { |
| 78 send_extensions->push_back(extension.id); |
| 79 } |
| 80 } |
| 81 for (const webrtc::RtpExtension& extension : |
| 82 remote_encrypted_header_extensions_) { |
| 83 if (webrtc::RtpExtension::FindHeaderExtensionByUri( |
| 84 local_encrypted_header_extensions_, extension.uri)) { |
| 85 recv_extensions->push_back(extension.id); |
| 86 } |
| 87 } |
| 88 } |
| 89 |
69 bool SrtpFilter::SetRtpParams(int send_cs, | 90 bool SrtpFilter::SetRtpParams(int send_cs, |
70 const uint8_t* send_key, | 91 const uint8_t* send_key, |
71 int send_key_len, | 92 int send_key_len, |
72 int recv_cs, | 93 int recv_cs, |
73 const uint8_t* recv_key, | 94 const uint8_t* recv_key, |
74 int recv_key_len) { | 95 int recv_key_len) { |
75 if (IsActive()) { | 96 if (IsActive()) { |
76 LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active"; | 97 LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active"; |
77 return false; | 98 return false; |
78 } | 99 } |
79 CreateSrtpSessions(); | 100 CreateSrtpSessions(); |
80 if (!send_session_->SetSend(send_cs, send_key, send_key_len)) | 101 std::vector<int> send_encrypted_header_extensions; |
| 102 std::vector<int> recv_encrypted_header_extensions; |
| 103 |
| 104 GetSendRecvEncryptedHeaderExtensions(&send_encrypted_header_extensions, |
| 105 &recv_encrypted_header_extensions); |
| 106 send_session_->SetEncryptedHeaderExtensions( |
| 107 send_encrypted_header_extensions); |
| 108 if (!send_session_->SetSend(send_cs, send_key, send_key_len)) { |
81 return false; | 109 return false; |
| 110 } |
82 | 111 |
83 if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) | 112 recv_session_->SetEncryptedHeaderExtensions( |
| 113 recv_encrypted_header_extensions); |
| 114 if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) { |
84 return false; | 115 return false; |
| 116 } |
85 | 117 |
86 state_ = ST_ACTIVE; | 118 state_ = ST_ACTIVE; |
87 | 119 |
88 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" | 120 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" |
89 << " send cipher_suite " << send_cs | 121 << " send cipher_suite " << send_cs |
90 << " recv cipher_suite " << recv_cs; | 122 << " recv cipher_suite " << recv_cs; |
91 return true; | 123 return true; |
92 } | 124 } |
93 | 125 |
| 126 bool SrtpFilter::UpdateRtpParams(int send_cs, |
| 127 const uint8_t* send_key, |
| 128 int send_key_len, |
| 129 int recv_cs, |
| 130 const uint8_t* recv_key, |
| 131 int recv_key_len) { |
| 132 if (!IsActive()) { |
| 133 LOG(LS_ERROR) << "Tried to update SRTP Params when filter is not active"; |
| 134 return false; |
| 135 } |
| 136 std::vector<int> send_encrypted_header_extensions; |
| 137 std::vector<int> recv_encrypted_header_extensions; |
| 138 |
| 139 GetSendRecvEncryptedHeaderExtensions(&send_encrypted_header_extensions, |
| 140 &recv_encrypted_header_extensions); |
| 141 send_session_->SetEncryptedHeaderExtensions( |
| 142 send_encrypted_header_extensions); |
| 143 if (!send_session_->UpdateSend(send_cs, send_key, send_key_len)) { |
| 144 return false; |
| 145 } |
| 146 |
| 147 recv_session_->SetEncryptedHeaderExtensions( |
| 148 recv_encrypted_header_extensions); |
| 149 if (!recv_session_->UpdateRecv(recv_cs, recv_key, recv_key_len)) { |
| 150 return false; |
| 151 } |
| 152 |
| 153 LOG(LS_INFO) << "SRTP updated with negotiated parameters:" |
| 154 << " send cipher_suite " << send_cs |
| 155 << " recv cipher_suite " << recv_cs; |
| 156 return true; |
| 157 } |
| 158 |
94 // This function is provided separately because DTLS-SRTP behaves | 159 // This function is provided separately because DTLS-SRTP behaves |
95 // differently in RTP/RTCP mux and non-mux modes. | 160 // differently in RTP/RTCP mux and non-mux modes. |
96 // | 161 // |
97 // - In the non-muxed case, RTP and RTCP are keyed with different | 162 // - In the non-muxed case, RTP and RTCP are keyed with different |
98 // keys (from different DTLS handshakes), and so we need a new | 163 // keys (from different DTLS handshakes), and so we need a new |
99 // SrtpSession. | 164 // SrtpSession. |
100 // - In the muxed case, they are keyed with the same keys, so | 165 // - In the muxed case, they are keyed with the same keys, so |
101 // this function is not needed | 166 // this function is not needed |
102 bool SrtpFilter::SetRtcpParams(int send_cs, | 167 bool SrtpFilter::SetRtcpParams(int send_cs, |
103 const uint8_t* send_key, | 168 const uint8_t* send_key, |
104 int send_key_len, | 169 int send_key_len, |
105 int recv_cs, | 170 int recv_cs, |
106 const uint8_t* recv_key, | 171 const uint8_t* recv_key, |
107 int recv_key_len) { | 172 int recv_key_len) { |
108 // This can only be called once, but can be safely called after | 173 // This can only be called once, but can be safely called after |
109 // SetRtpParams | 174 // SetRtpParams |
110 if (send_rtcp_session_ || recv_rtcp_session_) { | 175 if (send_rtcp_session_ || recv_rtcp_session_) { |
111 LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; | 176 LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; |
112 return false; | 177 return false; |
113 } | 178 } |
114 | 179 |
115 send_rtcp_session_.reset(new SrtpSession()); | 180 send_rtcp_session_.reset(new SrtpSession()); |
116 SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError); | 181 SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError); |
117 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); | 182 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)) | 183 if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) { |
119 return false; | 184 return false; |
| 185 } |
120 | 186 |
121 recv_rtcp_session_.reset(new SrtpSession()); | 187 recv_rtcp_session_.reset(new SrtpSession()); |
122 SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError); | 188 SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError); |
123 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_); | 189 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)) | 190 if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) { |
125 return false; | 191 return false; |
| 192 } |
126 | 193 |
127 LOG(LS_INFO) << "SRTCP activated with negotiated parameters:" | 194 LOG(LS_INFO) << "SRTCP activated with negotiated parameters:" |
128 << " send cipher_suite " << send_cs | 195 << " send cipher_suite " << send_cs |
129 << " recv cipher_suite " << recv_cs; | 196 << " recv cipher_suite " << recv_cs; |
130 | 197 |
131 return true; | 198 return true; |
132 } | 199 } |
133 | 200 |
134 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { | 201 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { |
135 if (!IsActive()) { | 202 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); | 302 send_session_->set_signal_silent_time(signal_silent_time_in_ms); |
236 RTC_CHECK(recv_session_); | 303 RTC_CHECK(recv_session_); |
237 recv_session_->set_signal_silent_time(signal_silent_time_in_ms); | 304 recv_session_->set_signal_silent_time(signal_silent_time_in_ms); |
238 if (send_rtcp_session_) | 305 if (send_rtcp_session_) |
239 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); | 306 send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); |
240 if (recv_rtcp_session_) | 307 if (recv_rtcp_session_) |
241 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); | 308 recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms); |
242 } | 309 } |
243 } | 310 } |
244 | 311 |
| 312 void SrtpFilter::SetEncryptedHeaderExtensions(ContentSource source, |
| 313 const std::vector<webrtc::RtpExtension>& extensions) { |
| 314 if (source == CS_LOCAL) { |
| 315 local_encrypted_header_extensions_ = extensions; |
| 316 } else { |
| 317 remote_encrypted_header_extensions_ = extensions; |
| 318 } |
| 319 } |
| 320 |
245 bool SrtpFilter::ExpectOffer(ContentSource source) { | 321 bool SrtpFilter::ExpectOffer(ContentSource source) { |
246 return ((state_ == ST_INIT) || | 322 return ((state_ == ST_INIT) || |
247 (state_ == ST_ACTIVE) || | 323 (state_ == ST_ACTIVE) || |
248 (state_ == ST_SENTOFFER && source == CS_LOCAL) || | 324 (state_ == ST_SENTOFFER && source == CS_LOCAL) || |
249 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || | 325 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || |
250 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || | 326 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || |
251 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); | 327 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); |
252 } | 328 } |
253 | 329 |
254 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, | 330 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. | 476 // TODO(juberti): Zero these buffers after use. |
401 bool ret; | 477 bool ret; |
402 rtc::Buffer send_key(send_key_len + send_salt_len); | 478 rtc::Buffer send_key(send_key_len + send_salt_len); |
403 rtc::Buffer recv_key(recv_key_len + recv_salt_len); | 479 rtc::Buffer recv_key(recv_key_len + recv_salt_len); |
404 ret = (ParseKeyParams(send_params.key_params, send_key.data(), | 480 ret = (ParseKeyParams(send_params.key_params, send_key.data(), |
405 send_key.size()) && | 481 send_key.size()) && |
406 ParseKeyParams(recv_params.key_params, recv_key.data(), | 482 ParseKeyParams(recv_params.key_params, recv_key.data(), |
407 recv_key.size())); | 483 recv_key.size())); |
408 if (ret) { | 484 if (ret) { |
409 CreateSrtpSessions(); | 485 CreateSrtpSessions(); |
| 486 std::vector<int> send_encrypted_header_extensions; |
| 487 std::vector<int> recv_encrypted_header_extensions; |
| 488 |
| 489 GetSendRecvEncryptedHeaderExtensions(&send_encrypted_header_extensions, |
| 490 &recv_encrypted_header_extensions); |
| 491 send_session_->SetEncryptedHeaderExtensions( |
| 492 send_encrypted_header_extensions); |
| 493 recv_session_->SetEncryptedHeaderExtensions( |
| 494 recv_encrypted_header_extensions); |
410 ret = (send_session_->SetSend( | 495 ret = (send_session_->SetSend( |
411 rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), | 496 rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), |
412 send_key.data(), send_key.size()) && | 497 send_key.data(), send_key.size()) && |
413 recv_session_->SetRecv( | 498 recv_session_->SetRecv( |
414 rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), | 499 rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), |
415 recv_key.data(), recv_key.size())); | 500 recv_key.data(), recv_key.size())); |
416 } | 501 } |
417 if (ret) { | 502 if (ret) { |
418 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" | 503 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" |
419 << " send cipher_suite " << send_params.cipher_suite | 504 << " send cipher_suite " << send_params.cipher_suite |
420 << " recv cipher_suite " << recv_params.cipher_suite; | 505 << " recv cipher_suite " << recv_params.cipher_suite; |
421 applied_send_params_ = send_params; | 506 applied_send_params_ = send_params; |
422 applied_recv_params_ = recv_params; | 507 applied_recv_params_ = recv_params; |
423 } else { | 508 } else { |
424 LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; | 509 LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; |
425 } | 510 } |
426 return ret; | 511 return ret; |
427 } | 512 } |
428 | 513 |
429 bool SrtpFilter::ResetParams() { | 514 bool SrtpFilter::ResetParams() { |
430 offer_params_.clear(); | 515 offer_params_.clear(); |
431 state_ = ST_INIT; | 516 state_ = ST_INIT; |
432 send_session_ = nullptr; | 517 send_session_ = nullptr; |
433 recv_session_ = nullptr; | 518 recv_session_ = nullptr; |
434 send_rtcp_session_ = nullptr; | 519 send_rtcp_session_ = nullptr; |
435 recv_rtcp_session_ = nullptr; | 520 recv_rtcp_session_ = nullptr; |
| 521 local_encrypted_header_extensions_.clear(); |
| 522 remote_encrypted_header_extensions_.clear(); |
436 LOG(LS_INFO) << "SRTP reset to init state"; | 523 LOG(LS_INFO) << "SRTP reset to init state"; |
437 return true; | 524 return true; |
438 } | 525 } |
439 | 526 |
440 bool SrtpFilter::ParseKeyParams(const std::string& key_params, | 527 bool SrtpFilter::ParseKeyParams(const std::string& key_params, |
441 uint8_t* key, | 528 uint8_t* key, |
442 size_t len) { | 529 size_t len) { |
443 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" | 530 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" |
444 | 531 |
445 // Fail if key-method is wrong. | 532 // Fail if key-method is wrong. |
(...skipping 28 matching lines...) Expand all Loading... |
474 if (session_) { | 561 if (session_) { |
475 srtp_set_user_data(session_, nullptr); | 562 srtp_set_user_data(session_, nullptr); |
476 srtp_dealloc(session_); | 563 srtp_dealloc(session_); |
477 } | 564 } |
478 } | 565 } |
479 | 566 |
480 bool SrtpSession::SetSend(int cs, const uint8_t* key, size_t len) { | 567 bool SrtpSession::SetSend(int cs, const uint8_t* key, size_t len) { |
481 return SetKey(ssrc_any_outbound, cs, key, len); | 568 return SetKey(ssrc_any_outbound, cs, key, len); |
482 } | 569 } |
483 | 570 |
| 571 bool SrtpSession::UpdateSend(int cs, const uint8_t* key, size_t len) { |
| 572 return UpdateKey(ssrc_any_outbound, cs, key, len); |
| 573 } |
| 574 |
484 bool SrtpSession::SetRecv(int cs, const uint8_t* key, size_t len) { | 575 bool SrtpSession::SetRecv(int cs, const uint8_t* key, size_t len) { |
485 return SetKey(ssrc_any_inbound, cs, key, len); | 576 return SetKey(ssrc_any_inbound, cs, key, len); |
486 } | 577 } |
487 | 578 |
| 579 bool SrtpSession::UpdateRecv(int cs, const uint8_t* key, size_t len) { |
| 580 return UpdateKey(ssrc_any_inbound, cs, key, len); |
| 581 } |
| 582 |
488 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { | 583 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { |
489 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 584 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
490 if (!session_) { | 585 if (!session_) { |
491 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; | 586 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; |
492 return false; | 587 return false; |
493 } | 588 } |
494 | 589 |
495 int need_len = in_len + rtp_auth_tag_len_; // NOLINT | 590 int need_len = in_len + rtp_auth_tag_len_; // NOLINT |
496 if (max_len < need_len) { | 591 if (max_len < need_len) { |
497 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " | 592 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 *index = static_cast<int64_t>( | 742 *index = static_cast<int64_t>( |
648 rtc::NetworkToHost64( | 743 rtc::NetworkToHost64( |
649 srtp_rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); | 744 srtp_rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); |
650 return true; | 745 return true; |
651 } | 746 } |
652 | 747 |
653 void SrtpSession::set_signal_silent_time(int signal_silent_time_in_ms) { | 748 void SrtpSession::set_signal_silent_time(int signal_silent_time_in_ms) { |
654 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); | 749 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); |
655 } | 750 } |
656 | 751 |
657 bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) { | 752 bool SrtpSession::DoSetKey(int type, int cs, const uint8_t* key, size_t len) { |
658 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 753 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
659 if (session_) { | |
660 LOG(LS_ERROR) << "Failed to create SRTP session: " | |
661 << "SRTP session already created"; | |
662 return false; | |
663 } | |
664 | |
665 if (!Init()) { | |
666 return false; | |
667 } | |
668 | 754 |
669 srtp_policy_t policy; | 755 srtp_policy_t policy; |
670 memset(&policy, 0, sizeof(policy)); | 756 memset(&policy, 0, sizeof(policy)); |
671 if (cs == rtc::SRTP_AES128_CM_SHA1_80) { | 757 if (cs == rtc::SRTP_AES128_CM_SHA1_80) { |
672 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); | 758 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); |
673 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); | 759 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); |
674 } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) { | 760 } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) { |
675 // RTP HMAC is shortened to 32 bits, but RTCP remains 80 bits. | 761 // RTP HMAC is shortened to 32 bits, but RTCP remains 80 bits. |
676 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); | 762 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); |
677 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); | 763 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); |
678 } else if (cs == rtc::SRTP_AEAD_AES_128_GCM) { | 764 } else if (cs == rtc::SRTP_AEAD_AES_128_GCM) { |
679 srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp); | 765 srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp); |
680 srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp); | 766 srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp); |
681 } else if (cs == rtc::SRTP_AEAD_AES_256_GCM) { | 767 } else if (cs == rtc::SRTP_AEAD_AES_256_GCM) { |
682 srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp); | 768 srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp); |
683 srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp); | 769 srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp); |
684 } else { | 770 } else { |
685 LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" | 771 LOG(LS_WARNING) << "Failed to " << (session_ ? "update" : "create") |
686 << " cipher_suite " << cs; | 772 << " SRTP session: unsupported cipher_suite " << cs; |
687 return false; | 773 return false; |
688 } | 774 } |
689 | 775 |
690 int expected_key_len; | 776 int expected_key_len; |
691 int expected_salt_len; | 777 int expected_salt_len; |
692 if (!rtc::GetSrtpKeyAndSaltLengths(cs, &expected_key_len, | 778 if (!rtc::GetSrtpKeyAndSaltLengths(cs, &expected_key_len, |
693 &expected_salt_len)) { | 779 &expected_salt_len)) { |
694 // This should never happen. | 780 // This should never happen. |
695 LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" | 781 LOG(LS_WARNING) << "Failed to " << (session_ ? "update" : "create") |
696 << " cipher_suite without length information" << cs; | 782 << " SRTP session: unsupported cipher_suite without length information" |
| 783 << cs; |
697 return false; | 784 return false; |
698 } | 785 } |
699 | 786 |
700 if (!key || | 787 if (!key || |
701 len != static_cast<size_t>(expected_key_len + expected_salt_len)) { | 788 len != static_cast<size_t>(expected_key_len + expected_salt_len)) { |
702 LOG(LS_WARNING) << "Failed to create SRTP session: invalid key"; | 789 LOG(LS_WARNING) << "Failed to " << (session_ ? "update" : "create") |
| 790 << " SRTP session: invalid key"; |
703 return false; | 791 return false; |
704 } | 792 } |
705 | 793 |
706 policy.ssrc.type = static_cast<srtp_ssrc_type_t>(type); | 794 policy.ssrc.type = static_cast<srtp_ssrc_type_t>(type); |
707 policy.ssrc.value = 0; | 795 policy.ssrc.value = 0; |
708 policy.key = const_cast<uint8_t*>(key); | 796 policy.key = const_cast<uint8_t*>(key); |
709 // TODO(astor) parse window size from WSH session-param | 797 // TODO(astor) parse window size from WSH session-param |
710 policy.window_size = 1024; | 798 policy.window_size = 1024; |
711 policy.allow_repeat_tx = 1; | 799 policy.allow_repeat_tx = 1; |
712 // If external authentication option is enabled, supply custom auth module | 800 // If external authentication option is enabled, supply custom auth module |
713 // id EXTERNAL_HMAC_SHA1 in the policy structure. | 801 // id EXTERNAL_HMAC_SHA1 in the policy structure. |
714 // We want to set this option only for rtp packets. | 802 // We want to set this option only for rtp packets. |
715 // By default policy structure is initialized to HMAC_SHA1. | 803 // By default policy structure is initialized to HMAC_SHA1. |
716 // Enable external HMAC authentication only for outgoing streams and only | 804 // Enable external HMAC authentication only for outgoing streams and only |
717 // for cipher suites that support it (i.e. only non-GCM cipher suites). | 805 // for cipher suites that support it (i.e. only non-GCM cipher suites). |
718 if (type == ssrc_any_outbound && IsExternalAuthEnabled() && | 806 if (type == ssrc_any_outbound && IsExternalAuthEnabled() && |
719 !rtc::IsGcmCryptoSuite(cs)) { | 807 !rtc::IsGcmCryptoSuite(cs)) { |
720 policy.rtp.auth_type = EXTERNAL_HMAC_SHA1; | 808 policy.rtp.auth_type = EXTERNAL_HMAC_SHA1; |
721 } | 809 } |
| 810 if (!encrypted_header_extensions_.empty()) { |
| 811 policy.enc_xtn_hdr = const_cast<int*>(&encrypted_header_extensions_[0]); |
| 812 policy.enc_xtn_hdr_count = encrypted_header_extensions_.size(); |
| 813 } |
722 policy.next = nullptr; | 814 policy.next = nullptr; |
723 | 815 |
724 int err = srtp_create(&session_, &policy); | 816 if (!session_) { |
725 if (err != srtp_err_status_ok) { | 817 int err = srtp_create(&session_, &policy); |
726 session_ = nullptr; | 818 if (err != srtp_err_status_ok) { |
727 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; | 819 session_ = nullptr; |
728 return false; | 820 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; |
| 821 return false; |
| 822 } |
| 823 srtp_set_user_data(session_, this); |
| 824 } else { |
| 825 int err = srtp_update(session_, &policy); |
| 826 if (err != srtp_err_status_ok) { |
| 827 LOG(LS_ERROR) << "Failed to update SRTP session, err=" << err; |
| 828 return false; |
| 829 } |
729 } | 830 } |
730 | 831 |
731 srtp_set_user_data(session_, this); | |
732 rtp_auth_tag_len_ = policy.rtp.auth_tag_len; | 832 rtp_auth_tag_len_ = policy.rtp.auth_tag_len; |
733 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; | 833 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; |
734 external_auth_active_ = (policy.rtp.auth_type == EXTERNAL_HMAC_SHA1); | 834 external_auth_active_ = (policy.rtp.auth_type == EXTERNAL_HMAC_SHA1); |
735 return true; | 835 return true; |
736 } | 836 } |
737 | 837 |
| 838 bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) { |
| 839 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 840 if (session_) { |
| 841 LOG(LS_ERROR) << "Failed to create SRTP session: " |
| 842 << "SRTP session already created"; |
| 843 return false; |
| 844 } |
| 845 |
| 846 if (!Init()) { |
| 847 return false; |
| 848 } |
| 849 |
| 850 return DoSetKey(type, cs, key, len); |
| 851 } |
| 852 |
| 853 bool SrtpSession::UpdateKey(int type, int cs, const uint8_t* key, size_t len) { |
| 854 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 855 if (!session_) { |
| 856 LOG(LS_ERROR) << "Failed to update non-existing SRTP session"; |
| 857 return false; |
| 858 } |
| 859 |
| 860 return DoSetKey(type, cs, key, len); |
| 861 } |
| 862 |
| 863 void SrtpSession::SetEncryptedHeaderExtensions( |
| 864 const std::vector<int>& encrypted_header_extensions) { |
| 865 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 866 encrypted_header_extensions_ = encrypted_header_extensions; |
| 867 } |
| 868 |
738 bool SrtpSession::Init() { | 869 bool SrtpSession::Init() { |
739 rtc::GlobalLockScope ls(&lock_); | 870 rtc::GlobalLockScope ls(&lock_); |
740 | 871 |
741 if (!inited_) { | 872 if (!inited_) { |
742 int err; | 873 int err; |
743 err = srtp_init(); | 874 err = srtp_init(); |
744 if (err != srtp_err_status_ok) { | 875 if (err != srtp_err_status_ok) { |
745 LOG(LS_ERROR) << "Failed to init SRTP, err=" << err; | 876 LOG(LS_ERROR) << "Failed to init SRTP, err=" << err; |
746 return false; | 877 return false; |
747 } | 878 } |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 if (stat->last_signal_time == 0 || | 1002 if (stat->last_signal_time == 0 || |
872 rtc::TimeDiff(current_time, stat->last_signal_time) > | 1003 rtc::TimeDiff(current_time, stat->last_signal_time) > |
873 signal_silent_time_) { | 1004 signal_silent_time_) { |
874 SignalSrtpError(key.ssrc, key.mode, key.error); | 1005 SignalSrtpError(key.ssrc, key.mode, key.error); |
875 stat->last_signal_time = current_time; | 1006 stat->last_signal_time = current_time; |
876 } | 1007 } |
877 } | 1008 } |
878 } | 1009 } |
879 | 1010 |
880 } // namespace cricket | 1011 } // namespace cricket |
OLD | NEW |