| Index: webrtc/pc/srtpfilter.cc
|
| diff --git a/webrtc/pc/srtpfilter.cc b/webrtc/pc/srtpfilter.cc
|
| index f8537f3dd678fedd72a74b80c7ff8f2efb8fe5b4..63e2d60f492759240b037ef4d0ca0f71c6b28c00 100644
|
| --- a/webrtc/pc/srtpfilter.cc
|
| +++ b/webrtc/pc/srtpfilter.cc
|
| @@ -77,11 +77,17 @@ bool SrtpFilter::SetRtpParams(int send_cs,
|
| return false;
|
| }
|
| CreateSrtpSessions();
|
| - if (!send_session_->SetSend(send_cs, send_key, send_key_len))
|
| + send_session_->SetEncryptedHeaderExtensionIds(
|
| + send_encrypted_header_extension_ids_);
|
| + if (!send_session_->SetSend(send_cs, send_key, send_key_len)) {
|
| return false;
|
| + }
|
|
|
| - if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len))
|
| + recv_session_->SetEncryptedHeaderExtensionIds(
|
| + recv_encrypted_header_extension_ids_);
|
| + if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) {
|
| return false;
|
| + }
|
|
|
| state_ = ST_ACTIVE;
|
|
|
| @@ -91,6 +97,34 @@ bool SrtpFilter::SetRtpParams(int send_cs,
|
| return true;
|
| }
|
|
|
| +bool SrtpFilter::UpdateRtpParams(int send_cs,
|
| + const uint8_t* send_key,
|
| + int send_key_len,
|
| + int recv_cs,
|
| + const uint8_t* recv_key,
|
| + int recv_key_len) {
|
| + if (!IsActive()) {
|
| + LOG(LS_ERROR) << "Tried to update SRTP Params when filter is not active";
|
| + return false;
|
| + }
|
| + send_session_->SetEncryptedHeaderExtensionIds(
|
| + send_encrypted_header_extension_ids_);
|
| + if (!send_session_->UpdateSend(send_cs, send_key, send_key_len)) {
|
| + return false;
|
| + }
|
| +
|
| + recv_session_->SetEncryptedHeaderExtensionIds(
|
| + recv_encrypted_header_extension_ids_);
|
| + if (!recv_session_->UpdateRecv(recv_cs, recv_key, recv_key_len)) {
|
| + return false;
|
| + }
|
| +
|
| + LOG(LS_INFO) << "SRTP updated with negotiated parameters:"
|
| + << " send cipher_suite " << send_cs
|
| + << " recv cipher_suite " << recv_cs;
|
| + return true;
|
| +}
|
| +
|
| // This function is provided separately because DTLS-SRTP behaves
|
| // differently in RTP/RTCP mux and non-mux modes.
|
| //
|
| @@ -115,14 +149,16 @@ bool SrtpFilter::SetRtcpParams(int send_cs,
|
| send_rtcp_session_.reset(new SrtpSession());
|
| SignalSrtpError.repeat(send_rtcp_session_->SignalSrtpError);
|
| send_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_);
|
| - if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len))
|
| + if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) {
|
| return false;
|
| + }
|
|
|
| recv_rtcp_session_.reset(new SrtpSession());
|
| SignalSrtpError.repeat(recv_rtcp_session_->SignalSrtpError);
|
| recv_rtcp_session_->set_signal_silent_time(signal_silent_time_in_ms_);
|
| - if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len))
|
| + if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) {
|
| return false;
|
| + }
|
|
|
| LOG(LS_INFO) << "SRTCP activated with negotiated parameters:"
|
| << " send cipher_suite " << send_cs
|
| @@ -242,6 +278,15 @@ void SrtpFilter::set_signal_silent_time(int signal_silent_time_in_ms) {
|
| }
|
| }
|
|
|
| +void SrtpFilter::SetEncryptedHeaderExtensionIds(ContentSource source,
|
| + const std::vector<int>& extension_ids) {
|
| + if (source == CS_LOCAL) {
|
| + send_encrypted_header_extension_ids_ = extension_ids;
|
| + } else {
|
| + recv_encrypted_header_extension_ids_ = extension_ids;
|
| + }
|
| +}
|
| +
|
| bool SrtpFilter::ExpectOffer(ContentSource source) {
|
| return ((state_ == ST_INIT) ||
|
| (state_ == ST_ACTIVE) ||
|
| @@ -407,6 +452,10 @@ bool SrtpFilter::ApplyParams(const CryptoParams& send_params,
|
| recv_key.size()));
|
| if (ret) {
|
| CreateSrtpSessions();
|
| + send_session_->SetEncryptedHeaderExtensionIds(
|
| + send_encrypted_header_extension_ids_);
|
| + recv_session_->SetEncryptedHeaderExtensionIds(
|
| + recv_encrypted_header_extension_ids_);
|
| ret = (send_session_->SetSend(
|
| rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite),
|
| send_key.data(), send_key.size()) &&
|
| @@ -481,10 +530,18 @@ bool SrtpSession::SetSend(int cs, const uint8_t* key, size_t len) {
|
| return SetKey(ssrc_any_outbound, cs, key, len);
|
| }
|
|
|
| +bool SrtpSession::UpdateSend(int cs, const uint8_t* key, size_t len) {
|
| + return UpdateKey(ssrc_any_outbound, cs, key, len);
|
| +}
|
| +
|
| bool SrtpSession::SetRecv(int cs, const uint8_t* key, size_t len) {
|
| return SetKey(ssrc_any_inbound, cs, key, len);
|
| }
|
|
|
| +bool SrtpSession::UpdateRecv(int cs, const uint8_t* key, size_t len) {
|
| + return UpdateKey(ssrc_any_inbound, cs, key, len);
|
| +}
|
| +
|
| bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
|
| RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
| if (!session_) {
|
| @@ -654,17 +711,8 @@ void SrtpSession::set_signal_silent_time(int signal_silent_time_in_ms) {
|
| srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms);
|
| }
|
|
|
| -bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) {
|
| +bool SrtpSession::DoSetKey(int type, int cs, const uint8_t* key, size_t len) {
|
| RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
| - if (session_) {
|
| - LOG(LS_ERROR) << "Failed to create SRTP session: "
|
| - << "SRTP session already created";
|
| - return false;
|
| - }
|
| -
|
| - if (!Init()) {
|
| - return false;
|
| - }
|
|
|
| srtp_policy_t policy;
|
| memset(&policy, 0, sizeof(policy));
|
| @@ -682,8 +730,8 @@ bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) {
|
| srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
|
| srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp);
|
| } else {
|
| - LOG(LS_WARNING) << "Failed to create SRTP session: unsupported"
|
| - << " cipher_suite " << cs;
|
| + LOG(LS_WARNING) << "Failed to " << (session_ ? "update" : "create")
|
| + << " SRTP session: unsupported cipher_suite " << cs;
|
| return false;
|
| }
|
|
|
| @@ -692,14 +740,16 @@ bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) {
|
| if (!rtc::GetSrtpKeyAndSaltLengths(cs, &expected_key_len,
|
| &expected_salt_len)) {
|
| // This should never happen.
|
| - LOG(LS_WARNING) << "Failed to create SRTP session: unsupported"
|
| - << " cipher_suite without length information" << cs;
|
| + LOG(LS_WARNING) << "Failed to " << (session_ ? "update" : "create")
|
| + << " SRTP session: unsupported cipher_suite without length information"
|
| + << cs;
|
| return false;
|
| }
|
|
|
| if (!key ||
|
| len != static_cast<size_t>(expected_key_len + expected_salt_len)) {
|
| - LOG(LS_WARNING) << "Failed to create SRTP session: invalid key";
|
| + LOG(LS_WARNING) << "Failed to " << (session_ ? "update" : "create")
|
| + << " SRTP session: invalid key";
|
| return false;
|
| }
|
|
|
| @@ -719,22 +769,65 @@ bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) {
|
| !rtc::IsGcmCryptoSuite(cs)) {
|
| policy.rtp.auth_type = EXTERNAL_HMAC_SHA1;
|
| }
|
| + if (!encrypted_header_extension_ids_.empty()) {
|
| + policy.enc_xtn_hdr = const_cast<int*>(&encrypted_header_extension_ids_[0]);
|
| + policy.enc_xtn_hdr_count = encrypted_header_extension_ids_.size();
|
| + }
|
| policy.next = nullptr;
|
|
|
| - int err = srtp_create(&session_, &policy);
|
| - if (err != srtp_err_status_ok) {
|
| - session_ = nullptr;
|
| - LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err;
|
| - return false;
|
| + if (!session_) {
|
| + int err = srtp_create(&session_, &policy);
|
| + if (err != srtp_err_status_ok) {
|
| + session_ = nullptr;
|
| + LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err;
|
| + return false;
|
| + }
|
| + srtp_set_user_data(session_, this);
|
| + } else {
|
| + int err = srtp_update(session_, &policy);
|
| + if (err != srtp_err_status_ok) {
|
| + LOG(LS_ERROR) << "Failed to update SRTP session, err=" << err;
|
| + return false;
|
| + }
|
| }
|
|
|
| - srtp_set_user_data(session_, this);
|
| rtp_auth_tag_len_ = policy.rtp.auth_tag_len;
|
| rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len;
|
| external_auth_active_ = (policy.rtp.auth_type == EXTERNAL_HMAC_SHA1);
|
| return true;
|
| }
|
|
|
| +bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, size_t len) {
|
| + RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
| + if (session_) {
|
| + LOG(LS_ERROR) << "Failed to create SRTP session: "
|
| + << "SRTP session already created";
|
| + return false;
|
| + }
|
| +
|
| + if (!Init()) {
|
| + return false;
|
| + }
|
| +
|
| + return DoSetKey(type, cs, key, len);
|
| +}
|
| +
|
| +bool SrtpSession::UpdateKey(int type, int cs, const uint8_t* key, size_t len) {
|
| + RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
| + if (!session_) {
|
| + LOG(LS_ERROR) << "Failed to update non-existing SRTP session";
|
| + return false;
|
| + }
|
| +
|
| + return DoSetKey(type, cs, key, len);
|
| +}
|
| +
|
| +void SrtpSession::SetEncryptedHeaderExtensionIds(
|
| + const std::vector<int>& encrypted_header_extension_ids) {
|
| + RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
| + encrypted_header_extension_ids_ = encrypted_header_extension_ids;
|
| +}
|
| +
|
| bool SrtpSession::Init() {
|
| rtc::GlobalLockScope ls(&lock_);
|
|
|
|
|