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

Unified Diff: pc/dtlssrtptransport.cc

Issue 3012953002: Created the DtlsSrtpTransport.
Patch Set: Resolved the comments. Created 3 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: pc/dtlssrtptransport.cc
diff --git a/pc/dtlssrtptransport.cc b/pc/dtlssrtptransport.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3b89b5b2eb665a8876dd1c475a79edcc7eb33ca8
--- /dev/null
+++ b/pc/dtlssrtptransport.cc
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "pc/dtlssrtptransport.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "media/base/rtputils.h"
+#include "rtc_base/sslstreamadapter.h"
+
+namespace {
+// Value specified in RFC 5764.
+static const char kDtlsSrtpExporterLabel[] = "EXTRACTOR-dtls_srtp";
+} // namespace
+
+namespace webrtc {
+
+DtlsSrtpTransport::DtlsSrtpTransport(
+ std::unique_ptr<webrtc::SrtpTransport> transport)
+ : srtp_transport_(std::move(transport)) {
+ ConnectToSrtpTransport();
+}
+
+void DtlsSrtpTransport::ConnectToSrtpTransport() {
+ RTC_DCHECK(srtp_transport_);
+ srtp_transport_->SignalPacketReceived.connect(
+ this, &DtlsSrtpTransport::OnPacketReceived);
+ srtp_transport_->SignalReadyToSend.connect(this,
+ &DtlsSrtpTransport::OnReadyToSend);
+}
+
+void DtlsSrtpTransport::OnPacketReceived(bool rtcp,
+ rtc::CopyOnWriteBuffer* packet,
+ const rtc::PacketTime& packet_time) {
+ SignalPacketReceived(rtcp, packet, packet_time);
+}
+
+void DtlsSrtpTransport::OnReadyToSend(bool ready) {
+ SignalReadyToSend(ready);
+}
+
+bool DtlsSrtpTransport::SetupDtlsSrtp(bool rtcp) {
+ bool ret = false;
+
+ cricket::DtlsTransportInternal* transport =
+ rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_;
+ RTC_DCHECK(transport);
+ RTC_DCHECK(transport->IsDtlsActive());
+
+ int selected_crypto_suite;
+
+ if (!transport->GetSrtpCryptoSuite(&selected_crypto_suite)) {
+ LOG(LS_ERROR) << "No DTLS-SRTP selected crypto suite";
+ return false;
+ }
+
+ LOG(LS_INFO) << "Installing keys from DTLS-SRTP on "
+ << cricket::RtpRtcpStringLiteral(rtcp);
+
+ int key_len;
+ int salt_len;
+ if (!rtc::GetSrtpKeyAndSaltLengths(selected_crypto_suite, &key_len,
+ &salt_len)) {
+ LOG(LS_ERROR) << "Unknown DTLS-SRTP crypto suite" << selected_crypto_suite;
+ return false;
+ }
+
+ // OK, we're now doing DTLS (RFC 5764)
+ std::vector<unsigned char> dtls_buffer(key_len * 2 + salt_len * 2);
+
+ // RFC 5705 exporter using the RFC 5764 parameters
+ if (!transport->ExportKeyingMaterial(kDtlsSrtpExporterLabel, NULL, 0, false,
+ &dtls_buffer[0], dtls_buffer.size())) {
+ LOG(LS_WARNING) << "DTLS-SRTP key export failed";
+ RTC_NOTREACHED(); // This should never happen
+ return false;
+ }
+
+ // Sync up the keys with the DTLS-SRTP interface
+ std::vector<unsigned char> client_write_key(key_len + salt_len);
+ std::vector<unsigned char> server_write_key(key_len + salt_len);
+ size_t offset = 0;
+ memcpy(&client_write_key[0], &dtls_buffer[offset], key_len);
+ offset += key_len;
+ memcpy(&server_write_key[0], &dtls_buffer[offset], key_len);
+ offset += key_len;
+ memcpy(&client_write_key[key_len], &dtls_buffer[offset], salt_len);
+ offset += salt_len;
+ memcpy(&server_write_key[key_len], &dtls_buffer[offset], salt_len);
+
+ std::vector<unsigned char>*send_key, *recv_key;
+ rtc::SSLRole role;
+ if (!transport->GetSslRole(&role)) {
+ LOG(LS_WARNING) << "GetSslRole failed";
+ return false;
+ }
+
+ if (role == rtc::SSL_SERVER) {
+ send_key = &server_write_key;
+ recv_key = &client_write_key;
+ } else {
+ send_key = &client_write_key;
+ recv_key = &server_write_key;
+ }
+
+ if (rtcp) {
+ if (!IsActive()) {
+ RTC_DCHECK(srtp_transport_);
+ ret = srtp_transport_->SetRtcpParams(
+ selected_crypto_suite, &(*send_key)[0],
+ static_cast<int>(send_key->size()), selected_crypto_suite,
+ &(*recv_key)[0], static_cast<int>(recv_key->size()));
+ } else {
+ // RTCP doesn't need to call SetRtpParam because it is only used
+ // to make the updated encrypted RTP header extension IDs take effect.
+ ret = true;
+ }
+ } else {
+ RTC_DCHECK(srtp_transport_);
+ ret = srtp_transport_->SetRtpParams(selected_crypto_suite, &(*send_key)[0],
+ static_cast<int>(send_key->size()),
+ selected_crypto_suite, &(*recv_key)[0],
+ static_cast<int>(recv_key->size()));
+ }
+
+ if (!ret) {
+ LOG(LS_WARNING) << "DTLS-SRTP key installation failed";
+ }
+ active_ = ret;
+ return ret;
+}
+
+void DtlsSrtpTransport::SetSendEncryptedHeaderExtensionIds(
Taylor Brandstetter 2017/09/27 23:54:48 In a previous code review I mentioned that it may
+ const std::vector<int>& send_extension_ids) {
+ RTC_DCHECK(srtp_transport_);
Taylor Brandstetter 2017/09/27 23:54:48 nit: I don't know if adding these DCHECKS everywhe
+ srtp_transport_->SetSendEncryptedHeaderExtensionIds(send_extension_ids);
+}
+
+void DtlsSrtpTransport::SetRecvEncryptedHeaderExtensionIds(
+ const std::vector<int>& recv_extension_ids) {
+ RTC_DCHECK(srtp_transport_);
+ srtp_transport_->SetRecvEncryptedHeaderExtensionIds(recv_extension_ids);
+}
+
+void DtlsSrtpTransport::SetRtcpMuxEnabled(bool enable) {
+ RTC_DCHECK(srtp_transport_);
+ srtp_transport_->SetRtcpMuxEnabled(enable);
+}
+
+rtc::PacketTransportInternal* DtlsSrtpTransport::rtp_packet_transport() const {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->rtp_packet_transport();
+}
+
+void DtlsSrtpTransport::SetRtpPacketTransport(
+ rtc::PacketTransportInternal* rtp) {
+ RTC_DCHECK(srtp_transport_);
+ srtp_transport_->SetRtpPacketTransport(rtp);
+}
+
+PacketTransportInterface* DtlsSrtpTransport::GetRtpPacketTransport() const {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->GetRtpPacketTransport();
+}
+
+rtc::PacketTransportInternal* DtlsSrtpTransport::rtcp_packet_transport() const {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->rtcp_packet_transport();
+}
+
+void DtlsSrtpTransport::SetRtcpPacketTransport(
+ rtc::PacketTransportInternal* rtcp) {
+ RTC_DCHECK(srtp_transport_);
+ srtp_transport_->SetRtcpPacketTransport(rtcp);
+}
+
+PacketTransportInterface* DtlsSrtpTransport::GetRtcpPacketTransport() const {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->GetRtcpPacketTransport();
+}
+
+bool DtlsSrtpTransport::IsWritable(bool rtcp) const {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->IsWritable(rtcp);
+}
+
+bool DtlsSrtpTransport::SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
+ const rtc::PacketOptions& options,
+ int flags) {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->SendRtpPacket(packet, options, flags);
+}
+
+bool DtlsSrtpTransport::SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
+ const rtc::PacketOptions& options,
+ int flags) {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->SendRtcpPacket(packet, options, flags);
+}
+
+bool DtlsSrtpTransport::HandlesPayloadType(int payload_type) const {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->HandlesPayloadType(payload_type);
+}
+
+void DtlsSrtpTransport::AddHandledPayloadType(int payload_type) {
+ RTC_DCHECK(srtp_transport_);
+ srtp_transport_->AddHandledPayloadType(payload_type);
+}
+
+void DtlsSrtpTransport::ResetParams() {
+ active_ = false;
+ if (srtp_transport_) {
Taylor Brandstetter 2017/09/27 23:54:48 When will it be null?
+ srtp_transport_->ResetParams();
+ }
+}
+
+RTCError DtlsSrtpTransport::SetParameters(
+ const RtpTransportParameters& parameters) {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->SetParameters(parameters);
+}
+
+RtpTransportParameters DtlsSrtpTransport::GetParameters() const {
+ RTC_DCHECK(srtp_transport_);
+ return srtp_transport_->GetParameters();
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698