Expose DtlsTransport::remote_ssl_certificates
Bug: chromium:907849
Change-Id: If990d541099edb9a327230e1d78a03b406269885
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131951
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27558}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 84b0c0e..31dd898 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -93,6 +93,7 @@
"crypto_params.h",
"data_channel_interface.cc",
"data_channel_interface.h",
+ "dtls_transport_interface.cc",
"dtls_transport_interface.h",
"dtmf_sender_interface.h",
"ice_transport_interface.h",
diff --git a/api/DEPS b/api/DEPS
index 6afa3d7..34bdfe0 100644
--- a/api/DEPS
+++ b/api/DEPS
@@ -75,6 +75,7 @@
"dtls_transport_interface\.h": [
"+rtc_base/ref_count.h",
+ "+rtc_base/ssl_certificate.h",
],
"dtmf_sender_interface\.h": [
diff --git a/api/dtls_transport_interface.cc b/api/dtls_transport_interface.cc
new file mode 100644
index 0000000..2bb5049
--- /dev/null
+++ b/api/dtls_transport_interface.cc
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 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 "api/dtls_transport_interface.h"
+
+namespace webrtc {
+
+DtlsTransportInformation::DtlsTransportInformation()
+ : state_(DtlsTransportState::kNew) {}
+
+DtlsTransportInformation::DtlsTransportInformation(DtlsTransportState state)
+ : state_(state) {}
+
+DtlsTransportInformation::DtlsTransportInformation(
+ DtlsTransportState state,
+ std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates)
+ : state_(state),
+ remote_ssl_certificates_(std::move(remote_ssl_certificates)) {}
+
+DtlsTransportInformation::DtlsTransportInformation(
+ const DtlsTransportInformation& c)
+ : state_(c.state()),
+ remote_ssl_certificates_(c.remote_ssl_certificates()
+ ? c.remote_ssl_certificates()->Clone()
+ : nullptr) {}
+
+DtlsTransportInformation& DtlsTransportInformation::operator=(
+ const DtlsTransportInformation& c) {
+ state_ = c.state();
+ remote_ssl_certificates_ = c.remote_ssl_certificates()
+ ? c.remote_ssl_certificates()->Clone()
+ : nullptr;
+ return *this;
+}
+
+} // namespace webrtc
diff --git a/api/dtls_transport_interface.h b/api/dtls_transport_interface.h
index 7f35a23..0270043 100644
--- a/api/dtls_transport_interface.h
+++ b/api/dtls_transport_interface.h
@@ -11,10 +11,14 @@
#ifndef API_DTLS_TRANSPORT_INTERFACE_H_
#define API_DTLS_TRANSPORT_INTERFACE_H_
+#include <memory>
+#include <utility>
+
#include "api/ice_transport_interface.h"
#include "api/rtc_error.h"
#include "api/scoped_refptr.h"
#include "rtc_base/ref_count.h"
+#include "rtc_base/ssl_certificate.h"
namespace webrtc {
@@ -34,11 +38,28 @@
// DTLSTransport.
class DtlsTransportInformation {
public:
- explicit DtlsTransportInformation(DtlsTransportState state) : state_(state) {}
+ DtlsTransportInformation();
+ explicit DtlsTransportInformation(DtlsTransportState state);
+ DtlsTransportInformation(
+ DtlsTransportState state,
+ std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates);
+ // Copy and assign
+ DtlsTransportInformation(const DtlsTransportInformation& c);
+ DtlsTransportInformation& operator=(const DtlsTransportInformation& c);
+ // Move
+ DtlsTransportInformation(DtlsTransportInformation&& other) = default;
+ DtlsTransportInformation& operator=(DtlsTransportInformation&& other) =
+ default;
+
DtlsTransportState state() const { return state_; }
- // TODO(hta): Add remote certificate access
+ // The accessor returns a temporary pointer, it does not release ownership.
+ const rtc::SSLCertChain* remote_ssl_certificates() const {
+ return remote_ssl_certificates_.get();
+ }
+
private:
DtlsTransportState state_;
+ std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates_;
};
class DtlsTransportObserverInterface {
diff --git a/pc/dtls_transport.cc b/pc/dtls_transport.cc
index 38cef1e..9ce72a3 100644
--- a/pc/dtls_transport.cc
+++ b/pc/dtls_transport.cc
@@ -116,8 +116,15 @@
RTC_DCHECK_RUN_ON(owner_thread_);
rtc::CritScope scope(&lock_);
if (internal_dtls_transport_) {
- info_ = DtlsTransportInformation(
- TranslateState(internal_dtls_transport_->dtls_state()));
+ if (internal_dtls_transport_->dtls_state() ==
+ cricket::DTLS_TRANSPORT_CONNECTED) {
+ info_ = DtlsTransportInformation(
+ TranslateState(internal_dtls_transport_->dtls_state()),
+ internal_dtls_transport_->GetRemoteSSLCertChain());
+ } else {
+ info_ = DtlsTransportInformation(
+ TranslateState(internal_dtls_transport_->dtls_state()));
+ }
} else {
info_ = DtlsTransportInformation(DtlsTransportState::kClosed);
}
diff --git a/pc/dtls_transport_unittest.cc b/pc/dtls_transport_unittest.cc
index 0c27c1b..05f5440 100644
--- a/pc/dtls_transport_unittest.cc
+++ b/pc/dtls_transport_unittest.cc
@@ -31,6 +31,7 @@
void OnStateChange(DtlsTransportInformation info) override {
state_change_called_ = true;
states_.push_back(info.state());
+ info_ = info;
}
void OnError(RTCError error) override {}
@@ -44,6 +45,7 @@
}
bool state_change_called_ = false;
+ DtlsTransportInformation info_;
std::vector<DtlsTransportState> states_;
};
@@ -52,9 +54,12 @@
DtlsTransport* transport() { return transport_.get(); }
DtlsTransportObserverInterface* observer() { return &observer_; }
- void CreateTransport() {
+ void CreateTransport(rtc::FakeSSLCertificate* certificate = nullptr) {
auto cricket_transport = absl::make_unique<FakeDtlsTransport>(
"audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
+ if (certificate) {
+ cricket_transport->SetRemoteSSLCertificate(certificate);
+ }
transport_ =
new rtc::RefCountedObject<DtlsTransport>(std::move(cricket_transport));
}
@@ -113,4 +118,28 @@
kDefaultTimeout);
}
+TEST_F(DtlsTransportTest, CertificateAppearsOnConnect) {
+ rtc::FakeSSLCertificate fake_certificate("fake data");
+ CreateTransport(&fake_certificate);
+ transport()->RegisterObserver(observer());
+ CompleteDtlsHandshake();
+ ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
+ kDefaultTimeout);
+ EXPECT_TRUE(observer_.info_.remote_ssl_certificates() != nullptr);
+}
+
+TEST_F(DtlsTransportTest, CertificateDisappearsOnClose) {
+ rtc::FakeSSLCertificate fake_certificate("fake data");
+ CreateTransport(&fake_certificate);
+ transport()->RegisterObserver(observer());
+ CompleteDtlsHandshake();
+ ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
+ kDefaultTimeout);
+ EXPECT_TRUE(observer_.info_.remote_ssl_certificates() != nullptr);
+ transport()->Clear();
+ ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
+ kDefaultTimeout);
+ EXPECT_FALSE(observer_.info_.remote_ssl_certificates());
+}
+
} // namespace webrtc