Implemented the GetRemoteAudioSSLCertificate method.
This method returns the DTLS SSL certificate chain associated with the
audio transport on the remote side. This will become populated once the
DTLS connection with the peer has been completed.
TBR=deadbeef@webrtc.org
Bug: webrtc:8800
Change-Id: Ib90ccb3463415e798c17c187c5bdbfc4da26f11f
Reviewed-on: https://webrtc-review.googlesource.com/44140
Commit-Queue: Zhi Huang <zhihuang@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21785}
diff --git a/p2p/base/dtlstransport.cc b/p2p/base/dtlstransport.cc
index 179b032..0e7bd60 100644
--- a/p2p/base/dtlstransport.cc
+++ b/p2p/base/dtlstransport.cc
@@ -308,6 +308,15 @@
return dtls_->GetPeerCertificate();
}
+std::unique_ptr<rtc::SSLCertChain> DtlsTransport::GetRemoteSSLCertChain()
+ const {
+ if (!dtls_) {
+ return nullptr;
+ }
+
+ return dtls_->GetPeerSSLCertChain();
+}
+
bool DtlsTransport::ExportKeyingMaterial(const std::string& label,
const uint8_t* context,
size_t context_len,
diff --git a/p2p/base/dtlstransport.h b/p2p/base/dtlstransport.h
index e7b0c56..a4f4bcd 100644
--- a/p2p/base/dtlstransport.h
+++ b/p2p/base/dtlstransport.h
@@ -141,8 +141,14 @@
// Once DTLS has been established, this method retrieves the certificate in
// use by the remote peer, for use in external identity verification.
+ // TODO(zhihuang): Remove all the SSLCertificate versions of these methods,
+ // and replace them with the SSLCertChain versions. Implement the
+ // PeerConnection::GetRemoteSSLCertificate using the SSLCertChain version.
std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate() const override;
+ // Version of the above method that returns the full certificate chain.
+ std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain() const override;
+
// Once DTLS has established (i.e., this ice_transport is writable), this
// method extracts the keys negotiated during the DTLS handshake, for use in
// external encryption. DTLS-SRTP uses this to extract the needed SRTP keys.
diff --git a/p2p/base/dtlstransport_unittest.cc b/p2p/base/dtlstransport_unittest.cc
index cac78647..430b41d 100644
--- a/p2p/base/dtlstransport_unittest.cc
+++ b/p2p/base/dtlstransport_unittest.cc
@@ -256,7 +256,7 @@
size_t size,
const rtc::PacketTime& time,
int flags) {
- // Flags shouldn't be set on the underlying TransportChannel packets.
+ // Flags shouldn't be set on the underlying Transport packets.
ASSERT_EQ(0, flags);
// Look at the handshake packets to see what role we played.
@@ -291,15 +291,14 @@
rtc::SentPacket sent_packet_;
};
-// Base class for DtlsTransportChannelTest and DtlsEventOrderingTest, which
+// Base class for DtlsTransportTest and DtlsEventOrderingTest, which
// inherit from different variants of testing::Test.
//
// Note that this test always uses a FakeClock, due to the |fake_clock_| member
// variable.
-class DtlsTransportChannelTestBase {
+class DtlsTransportTestBase {
public:
- DtlsTransportChannelTestBase()
- : client1_("P1"), client2_("P2"), use_dtls_(false) {}
+ DtlsTransportTestBase() : client1_("P1"), client2_("P2"), use_dtls_(false) {}
void SetMaxProtocolVersions(rtc::SSLProtocolVersion c1,
rtc::SSLProtocolVersion c2) {
@@ -380,22 +379,21 @@
rtc::ScopedFakeClock fake_clock_;
DtlsTestClient client1_;
DtlsTestClient client2_;
- int channel_ct_;
bool use_dtls_;
rtc::SSLProtocolVersion ssl_expected_version_;
};
-class DtlsTransportChannelTest : public DtlsTransportChannelTestBase,
- public ::testing::Test {};
+class DtlsTransportTest : public DtlsTransportTestBase,
+ public ::testing::Test {};
// Connect without DTLS, and transfer RTP data.
-TEST_F(DtlsTransportChannelTest, TestTransferRtp) {
+TEST_F(DtlsTransportTest, TestTransferRtp) {
ASSERT_TRUE(Connect());
TestTransfer(1000, 100, /*srtp=*/false);
}
// Test that the SignalSentPacket signal is wired up.
-TEST_F(DtlsTransportChannelTest, TestSignalSentPacket) {
+TEST_F(DtlsTransportTest, TestSignalSentPacket) {
ASSERT_TRUE(Connect());
// Sanity check default value (-1).
ASSERT_EQ(client1_.sent_packet().send_time_ms, -1);
@@ -407,13 +405,13 @@
}
// Connect without DTLS, and transfer SRTP data.
-TEST_F(DtlsTransportChannelTest, TestTransferSrtp) {
+TEST_F(DtlsTransportTest, TestTransferSrtp) {
ASSERT_TRUE(Connect());
TestTransfer(1000, 100, /*srtp=*/true);
}
// Connect with DTLS, and transfer data over DTLS.
-TEST_F(DtlsTransportChannelTest, TestTransferDtls) {
+TEST_F(DtlsTransportTest, TestTransferDtls) {
PrepareDtls(rtc::KT_DEFAULT);
ASSERT_TRUE(Connect());
TestTransfer(1000, 100, /*srtp=*/false);
@@ -423,7 +421,7 @@
// Our DTLS implementation doesn't do this, but other implementations may;
// see https://tools.ietf.org/html/rfc6347#section-4.1.1.
// This has caused interoperability problems with ORTCLib in the past.
-TEST_F(DtlsTransportChannelTest, TestTransferDtlsCombineRecords) {
+TEST_F(DtlsTransportTest, TestTransferDtlsCombineRecords) {
PrepareDtls(rtc::KT_DEFAULT);
ASSERT_TRUE(Connect());
// Our DTLS implementation always sends one record per packet, so to simulate
@@ -435,8 +433,8 @@
TestTransfer(500, 100, /*srtp=*/false);
}
-class DtlsTransportChannelVersionTest
- : public DtlsTransportChannelTestBase,
+class DtlsTransportVersionTest
+ : public DtlsTransportTestBase,
public ::testing::TestWithParam<
::testing::tuple<rtc::SSLProtocolVersion, rtc::SSLProtocolVersion>> {
};
@@ -444,7 +442,7 @@
// Test that an acceptable cipher suite is negotiated when different versions
// of DTLS are supported. Note that it's IsAcceptableCipher that does the actual
// work.
-TEST_P(DtlsTransportChannelVersionTest, TestCipherSuiteNegotiation) {
+TEST_P(DtlsTransportVersionTest, TestCipherSuiteNegotiation) {
PrepareDtls(rtc::KT_DEFAULT);
SetMaxProtocolVersions(::testing::get<0>(GetParam()),
::testing::get<1>(GetParam()));
@@ -454,14 +452,14 @@
// Will test every combination of 1.0/1.2 on the client and server.
INSTANTIATE_TEST_CASE_P(
TestCipherSuiteNegotiation,
- DtlsTransportChannelVersionTest,
+ DtlsTransportVersionTest,
::testing::Combine(::testing::Values(rtc::SSL_PROTOCOL_DTLS_10,
rtc::SSL_PROTOCOL_DTLS_12),
::testing::Values(rtc::SSL_PROTOCOL_DTLS_10,
rtc::SSL_PROTOCOL_DTLS_12)));
// Connect with DTLS, negotiating DTLS-SRTP, and transfer SRTP using bypass.
-TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtp) {
+TEST_F(DtlsTransportTest, TestTransferDtlsSrtp) {
PrepareDtls(rtc::KT_DEFAULT);
ASSERT_TRUE(Connect());
TestTransfer(1000, 100, /*srtp=*/true);
@@ -469,14 +467,15 @@
// Connect with DTLS-SRTP, transfer an invalid SRTP packet, and expects -1
// returned.
-TEST_F(DtlsTransportChannelTest, TestTransferDtlsInvalidSrtpPacket) {
+TEST_F(DtlsTransportTest, TestTransferDtlsInvalidSrtpPacket) {
PrepareDtls(rtc::KT_DEFAULT);
ASSERT_TRUE(Connect());
EXPECT_EQ(-1, client1_.SendInvalidSrtpPacket(100));
}
-// Create a single channel with DTLS, and send normal data and SRTP data on it.
-TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpDemux) {
+// Create a single transport with DTLS, and send normal data and SRTP data on
+// it.
+TEST_F(DtlsTransportTest, TestTransferDtlsSrtpDemux) {
PrepareDtls(rtc::KT_DEFAULT);
ASSERT_TRUE(Connect());
TestTransfer(1000, 100, /*srtp=*/false);
@@ -484,7 +483,7 @@
}
// Test transferring when the "answerer" has the server role.
-TEST_F(DtlsTransportChannelTest, TestTransferDtlsSrtpAnswererIsPassive) {
+TEST_F(DtlsTransportTest, TestTransferDtlsSrtpAnswererIsPassive) {
PrepareDtls(rtc::KT_DEFAULT);
ASSERT_TRUE(Connect(/*client1_server=*/false));
TestTransfer(1000, 100, /*srtp=*/true);
@@ -492,7 +491,7 @@
// Test that renegotiation (setting same role and fingerprint again) can be
// started before the clients become connected in the first negotiation.
-TEST_F(DtlsTransportChannelTest, TestRenegotiateBeforeConnect) {
+TEST_F(DtlsTransportTest, TestRenegotiateBeforeConnect) {
PrepareDtls(rtc::KT_DEFAULT);
// Note: This is doing the same thing Connect normally does, minus some
// additional checks not relevant for this test.
@@ -506,7 +505,7 @@
}
// Test Certificates state after negotiation but before connection.
-TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) {
+TEST_F(DtlsTransportTest, TestCertificatesBeforeConnect) {
PrepareDtls(rtc::KT_DEFAULT);
Negotiate();
@@ -521,7 +520,7 @@
}
// Test Certificates state after connection.
-TEST_F(DtlsTransportChannelTest, TestCertificatesAfterConnect) {
+TEST_F(DtlsTransportTest, TestCertificatesAfterConnect) {
PrepareDtls(rtc::KT_DEFAULT);
ASSERT_TRUE(Connect());
@@ -548,7 +547,7 @@
// Each time a timeout occurs, the retransmission timer should be doubled up to
// 60 seconds. The timer defaults to 1 second, but for WebRTC we should be
// initializing it to 50ms.
-TEST_F(DtlsTransportChannelTest, TestRetransmissionSchedule) {
+TEST_F(DtlsTransportTest, TestRetransmissionSchedule) {
// We can only change the retransmission schedule with a recently-added
// BoringSSL API. Skip the test if not built with BoringSSL.
MAYBE_SKIP_TEST(IsBoringSsl);
@@ -609,7 +608,7 @@
};
class DtlsEventOrderingTest
- : public DtlsTransportChannelTestBase,
+ : public DtlsTransportTestBase,
public ::testing::TestWithParam<
::testing::tuple<std::vector<DtlsTransportEvent>, bool>> {
protected:
@@ -683,7 +682,7 @@
client2_.dtls_transport()->dtls_state(), kTimeout,
fake_clock_);
- // Channel should be writable iff there was a valid fingerprint.
+ // Transports should be writable iff there was a valid fingerprint.
EXPECT_EQ(valid_fingerprint, client1_.dtls_transport()->writable());
EXPECT_EQ(valid_fingerprint, client2_.dtls_transport()->writable());
diff --git a/p2p/base/dtlstransportinternal.h b/p2p/base/dtlstransportinternal.h
index 2acbda6..1af32ac 100644
--- a/p2p/base/dtlstransportinternal.h
+++ b/p2p/base/dtlstransportinternal.h
@@ -82,6 +82,9 @@
virtual std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate()
const = 0;
+ // Gets a copy of the remote side's SSL certificate chain.
+ virtual std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain() const = 0;
+
// Allows key material to be extracted for external encryption.
virtual bool ExportKeyingMaterial(const std::string& label,
const uint8_t* context,
diff --git a/p2p/base/fakedtlstransport.h b/p2p/base/fakedtlstransport.h
index 54b7018..391486c 100644
--- a/p2p/base/fakedtlstransport.h
+++ b/p2p/base/fakedtlstransport.h
@@ -169,6 +169,9 @@
remote_cert_->GetReference())
: nullptr;
}
+ std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain() const override {
+ return nullptr;
+ }
bool ExportKeyingMaterial(const std::string& label,
const uint8_t* context,
size_t context_len,