| Index: webrtc/pc/srtpfilter.cc
|
| diff --git a/webrtc/pc/srtpfilter.cc b/webrtc/pc/srtpfilter.cc
|
| index 549410510311650f302facf75876e67c21988bd3..c27931249e46ce72902b40f9061c20efc31752cf 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.
|
| //
|
| @@ -113,12 +147,14 @@ bool SrtpFilter::SetRtcpParams(int send_cs,
|
| }
|
|
|
| send_rtcp_session_.reset(new SrtpSession());
|
| - 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());
|
| - 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
|
| @@ -224,6 +260,15 @@ bool SrtpFilter::IsExternalAuthActive() const {
|
| return send_session_->IsExternalAuthActive();
|
| }
|
|
|
| +void SrtpFilter::SetEncryptedHeaderExtensionIds(ContentSource source,
|
| + const std::vector<int>& extension_ids) {
|
| + if (source == CS_LOCAL) {
|
| + recv_encrypted_header_extension_ids_ = extension_ids;
|
| + } else {
|
| + send_encrypted_header_extension_ids_ = extension_ids;
|
| + }
|
| +}
|
| +
|
| bool SrtpFilter::ExpectOffer(ContentSource source) {
|
| return ((state_ == ST_INIT) ||
|
| (state_ == ST_ACTIVE) ||
|
| @@ -384,6 +429,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()) &&
|
| @@ -456,10 +505,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_) {
|
| @@ -615,17 +672,9 @@ bool SrtpSession::GetSendStreamPacketIndex(void* p,
|
| 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;
|
| - }
|
| +bool SrtpSession::DoSetKey(int type, int cs, const uint8_t* key, size_t len) {
|
| + RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| srtp_policy_t policy;
|
| memset(&policy, 0, sizeof(policy));
|
| @@ -643,8 +692,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;
|
| }
|
|
|
| @@ -653,14 +702,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;
|
| }
|
|
|
| @@ -680,22 +731,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_);
|
|
|
|
|