Add GetRemoteAudioSSLCertificate() to PeerConnection

This method allows the client to get details about the SSL
certificate sent by the remote side in the DTLS handshake.

This functionality in this new method has been standardized in the
RTCDtlsTransport, but until we have that implemented we wish to
expose this functionality so clients do not need to depend on
WebRtcSession.

Bug: webrtc:8323
Change-Id: Ic964266dd7e734cec07289a147fd8d090d74ce6b
Reviewed-on: https://webrtc-review.googlesource.com/5641
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20129}
This commit is contained in:
Steve Anton 2017-10-03 10:03:10 -07:00 committed by Commit Bot
parent 8a6d8e0928
commit 8c0f7a7a70
3 changed files with 73 additions and 0 deletions

View File

@ -1285,6 +1285,18 @@ RTCError PeerConnection::SetBitrate(const BitrateParameters& bitrate) {
return RTCError::OK();
}
std::unique_ptr<rtc::SSLCertificate>
PeerConnection::GetRemoteAudioSSLCertificate() {
if (!session_) {
return nullptr;
}
auto* voice_channel = session_->voice_channel();
if (!voice_channel) {
return nullptr;
}
return GetRemoteSSLCertificate(voice_channel->transport_name());
}
bool PeerConnection::StartRtcEventLog(rtc::PlatformFile file,
int64_t max_size_bytes) {
return worker_thread()->Invoke<bool>(

View File

@ -70,6 +70,15 @@ class PeerConnection : public PeerConnectionInterface,
// directly via this getter.
virtual WebRtcSession* session() { return session_; }
// Gets the DTLS SSL certificate associated with the audio transport on the
// remote side. This will become populated once the DTLS connection with the
// peer has been completed, as indicated by the ICE connection state
// transitioning to kIceConnectionCompleted.
// Note that this will be removed once we implement RTCDtlsTransport which
// has standardized method for getting this information.
// See https://www.w3.org/TR/webrtc/#rtcdtlstransport-interface
std::unique_ptr<rtc::SSLCertificate> GetRemoteAudioSSLCertificate();
rtc::scoped_refptr<DtmfSenderInterface> CreateDtmfSender(
AudioTrackInterface* track) override;

View File

@ -25,6 +25,7 @@
#include "api/fakemetricsobserver.h"
#include "api/mediastreaminterface.h"
#include "api/peerconnectioninterface.h"
#include "api/peerconnectionproxy.h"
#include "api/test/fakeconstraints.h"
#include "media/engine/fakewebrtcvideoengine.h"
#include "p2p/base/p2pconstants.h"
@ -66,8 +67,10 @@ using webrtc::MockDataChannelObserver;
using webrtc::MockSetSessionDescriptionObserver;
using webrtc::MockStatsObserver;
using webrtc::ObserverInterface;
using webrtc::PeerConnection;
using webrtc::PeerConnectionInterface;
using webrtc::PeerConnectionFactory;
using webrtc::PeerConnectionProxy;
using webrtc::SessionDescriptionInterface;
using webrtc::StreamCollectionInterface;
@ -1290,6 +1293,55 @@ TEST_F(PeerConnectionIntegrationTest, EndToEndCallWithSdes) {
kMaxWaitForFramesMs);
}
// Tests that the GetRemoteAudioSSLCertificate method returns the remote DTLS
// certificate once the DTLS handshake has finished.
TEST_F(PeerConnectionIntegrationTest,
GetRemoteAudioSSLCertificateReturnsExchangedCertificate) {
auto GetRemoteAudioSSLCertificate = [](PeerConnectionWrapper* wrapper) {
auto pci = reinterpret_cast<PeerConnectionProxy*>(wrapper->pc());
auto pc = reinterpret_cast<PeerConnection*>(pci->internal());
return pc->GetRemoteAudioSSLCertificate();
};
auto caller_cert = rtc::RTCCertificate::FromPEM(kRsaPems[0]);
auto callee_cert = rtc::RTCCertificate::FromPEM(kRsaPems[1]);
// Configure each side with a known certificate so they can be compared later.
PeerConnectionInterface::RTCConfiguration caller_config;
caller_config.enable_dtls_srtp.emplace(true);
caller_config.certificates.push_back(caller_cert);
PeerConnectionInterface::RTCConfiguration callee_config;
callee_config.enable_dtls_srtp.emplace(true);
callee_config.certificates.push_back(callee_cert);
ASSERT_TRUE(
CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
ConnectFakeSignaling();
// When first initialized, there should not be a remote SSL certificate (and
// calling this method should not crash).
EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(caller()));
EXPECT_EQ(nullptr, GetRemoteAudioSSLCertificate(callee()));
caller()->AddAudioOnlyMediaStream();
callee()->AddAudioOnlyMediaStream();
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout);
// Once DTLS has been connected, each side should return the other's SSL
// certificate when calling GetRemoteAudioSSLCertificate.
auto caller_remote_cert = GetRemoteAudioSSLCertificate(caller());
ASSERT_TRUE(caller_remote_cert);
EXPECT_EQ(callee_cert->ssl_certificate().ToPEMString(),
caller_remote_cert->ToPEMString());
auto callee_remote_cert = GetRemoteAudioSSLCertificate(callee());
ASSERT_TRUE(callee_remote_cert);
EXPECT_EQ(caller_cert->ssl_certificate().ToPEMString(),
callee_remote_cert->ToPEMString());
}
// This test sets up a call between two parties (using DTLS) and tests that we
// can get a video aspect ratio of 16:9.
TEST_F(PeerConnectionIntegrationTest, SendAndReceive16To9AspectRatio) {