A bunch of interfaces: Return scoped_ptr<SSLCertificate>

Instead of using a raw pointer output parameter. This affects

  SSLStreamAdapter::GetPeerCertificate
  Transport::GetRemoteSSLCertificate
  TransportChannel::GetRemoteSSLCertificate
  TransportController::GetRemoteSSLCertificate
  WebRtcSession::GetRemoteSSLCertificate

This is a good idea in general, but will also be very convenient when
scoped_ptr is gone, since unique_ptr doesn't have an .accept() method.

BUG=webrtc:5520

Review URL: https://codereview.webrtc.org/1802013002

Cr-Commit-Position: refs/heads/master@{#12262}
diff --git a/webrtc/api/statscollector.cc b/webrtc/api/statscollector.cc
index 0182a37..0901fc6 100644
--- a/webrtc/api/statscollector.cc
+++ b/webrtc/api/statscollector.cc
@@ -702,9 +702,10 @@
         local_cert_report_id = r->id();
     }
 
-    rtc::scoped_ptr<rtc::SSLCertificate> cert;
-    if (pc_->session()->GetRemoteSSLCertificate(
-            transport_iter.second.transport_name, cert.accept())) {
+    rtc::scoped_ptr<rtc::SSLCertificate> cert =
+        pc_->session()->GetRemoteSSLCertificate(
+            transport_iter.second.transport_name);
+    if (cert) {
       StatsReport* r = AddCertificateReports(cert.get());
       if (r)
         remote_cert_report_id = r->id();
diff --git a/webrtc/api/statscollector_unittest.cc b/webrtc/api/statscollector_unittest.cc
index 3b04383..5873e73 100644
--- a/webrtc/api/statscollector_unittest.cc
+++ b/webrtc/api/statscollector_unittest.cc
@@ -82,9 +82,15 @@
   MOCK_METHOD2(GetLocalCertificate,
                bool(const std::string& transport_name,
                     rtc::scoped_refptr<rtc::RTCCertificate>* certificate));
-  MOCK_METHOD2(GetRemoteSSLCertificate,
-               bool(const std::string& transport_name,
-                    rtc::SSLCertificate** cert));
+
+  // Workaround for gmock's inability to cope with move-only return values.
+  rtc::scoped_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate(
+      const std::string& transport_name) override {
+    return rtc::scoped_ptr<rtc::SSLCertificate>(
+        GetRemoteSSLCertificate_ReturnsRawPointer(transport_name));
+  }
+  MOCK_METHOD1(GetRemoteSSLCertificate_ReturnsRawPointer,
+               rtc::SSLCertificate*(const std::string& transport_name));
 };
 
 // The factory isn't really used; it just satisfies the base PeerConnection.
@@ -662,10 +668,11 @@
     VerifyVoiceReceiverInfoReport(track_report, *voice_receiver_info);
   }
 
-  void TestCertificateReports(const rtc::FakeSSLCertificate& local_cert,
-                              const std::vector<std::string>& local_ders,
-                              const rtc::FakeSSLCertificate& remote_cert,
-                              const std::vector<std::string>& remote_ders) {
+  void TestCertificateReports(
+      const rtc::FakeSSLCertificate& local_cert,
+      const std::vector<std::string>& local_ders,
+      rtc::scoped_ptr<rtc::FakeSSLCertificate> remote_cert,
+      const std::vector<std::string>& remote_ders) {
     StatsCollectorForTest stats(&pc_);
 
     StatsReports reports;  // returned values.
@@ -694,10 +701,9 @@
     EXPECT_CALL(session_,
                 GetLocalCertificate(transport_stats.transport_name, _))
         .WillOnce(DoAll(SetArgPointee<1>(local_certificate), Return(true)));
-    EXPECT_CALL(session_,
-                GetRemoteSSLCertificate(transport_stats.transport_name, _))
-        .WillOnce(
-            DoAll(SetArgPointee<1>(remote_cert.GetReference()), Return(true)));
+    EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(
+                              transport_stats.transport_name))
+        .WillOnce(Return(remote_cert.release()));
     EXPECT_CALL(session_, GetTransportStats(_))
       .WillOnce(DoAll(SetArgPointee<0>(session_stats),
                       Return(true)));
@@ -807,8 +813,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   const char kVideoChannelName[] = "video";
 
@@ -853,8 +859,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   const char kVideoChannelName[] = "video";
 
@@ -965,8 +971,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   const char kVideoChannelName[] = "video";
   InitSessionStats(kVideoChannelName);
@@ -1037,8 +1043,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
   // The transport_name known by the video channel.
@@ -1121,8 +1127,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   MockVideoMediaChannel* media_channel = new MockVideoMediaChannel();
   // The transport_name known by the video channel.
@@ -1172,8 +1178,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   const char kVideoChannelName[] = "video";
   InitSessionStats(kVideoChannelName);
@@ -1333,9 +1339,11 @@
   remote_ders[1] = "non-";
   remote_ders[2] = "intersecting";
   remote_ders[3] = "set";
-  rtc::FakeSSLCertificate remote_cert(DersToPems(remote_ders));
+  rtc::scoped_ptr<rtc::FakeSSLCertificate> remote_cert(
+      new rtc::FakeSSLCertificate(DersToPems(remote_ders)));
 
-  TestCertificateReports(local_cert, local_ders, remote_cert, remote_ders);
+  TestCertificateReports(local_cert, local_ders, std::move(remote_cert),
+                         remote_ders);
 }
 
 // This test verifies that all certificates without chains are correctly
@@ -1347,10 +1355,12 @@
 
   // Build remote certificate.
   std::string remote_der = "This is somebody else's der.";
-  rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
+  rtc::scoped_ptr<rtc::FakeSSLCertificate> remote_cert(
+      new rtc::FakeSSLCertificate(DerToPem(remote_der)));
 
   TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
-                         remote_cert, std::vector<std::string>(1, remote_der));
+                         std::move(remote_cert),
+                         std::vector<std::string>(1, remote_der));
 }
 
 // This test verifies that the stats are generated correctly when no
@@ -1360,8 +1370,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   StatsReports reports;  // returned values.
 
@@ -1417,8 +1427,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   StatsReports reports;  // returned values.
 
@@ -1469,11 +1479,12 @@
 
   // Build a remote certificate with an unsupported digest algorithm.
   std::string remote_der = "This is somebody else's der.";
-  rtc::FakeSSLCertificate remote_cert(DerToPem(remote_der));
-  remote_cert.set_digest_algorithm("foobar");
+  rtc::scoped_ptr<rtc::FakeSSLCertificate> remote_cert(
+      new rtc::FakeSSLCertificate(DerToPem(remote_der)));
+  remote_cert->set_digest_algorithm("foobar");
 
   TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
-                         remote_cert, std::vector<std::string>());
+                         std::move(remote_cert), std::vector<std::string>());
 }
 
 // This test verifies that a local stats object can get statistics via
@@ -1483,8 +1494,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   // The transport_name known by the voice channel.
@@ -1518,8 +1529,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   // The transport_name known by the voice channel.
@@ -1547,8 +1558,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   // The transport_name known by the voice channel.
@@ -1608,8 +1619,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   // The transport_name known by the voice channel.
@@ -1695,8 +1706,8 @@
 
   EXPECT_CALL(session_, GetLocalCertificate(_, _))
       .WillRepeatedly(Return(false));
-  EXPECT_CALL(session_, GetRemoteSSLCertificate(_, _))
-      .WillRepeatedly(Return(false));
+  EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_))
+      .WillRepeatedly(Return(nullptr));
 
   MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel();
   // The transport_name known by the voice channel.
diff --git a/webrtc/api/webrtcsession.cc b/webrtc/api/webrtcsession.cc
index 19f5aa4..f546285 100644
--- a/webrtc/api/webrtcsession.cc
+++ b/webrtc/api/webrtcsession.cc
@@ -1039,10 +1039,10 @@
                                                     certificate);
 }
 
-bool WebRtcSession::GetRemoteSSLCertificate(const std::string& transport_name,
-                                            rtc::SSLCertificate** cert) {
+rtc::scoped_ptr<rtc::SSLCertificate> WebRtcSession::GetRemoteSSLCertificate(
+    const std::string& transport_name) {
   ASSERT(signaling_thread()->IsCurrent());
-  return transport_controller_->GetRemoteSSLCertificate(transport_name, cert);
+  return transport_controller_->GetRemoteSSLCertificate(transport_name);
 }
 
 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) {
diff --git a/webrtc/api/webrtcsession.h b/webrtc/api/webrtcsession.h
index 6164731..01ec526 100644
--- a/webrtc/api/webrtcsession.h
+++ b/webrtc/api/webrtcsession.h
@@ -292,8 +292,8 @@
       rtc::scoped_refptr<rtc::RTCCertificate>* certificate);
 
   // Caller owns returned certificate
-  virtual bool GetRemoteSSLCertificate(const std::string& transport_name,
-                                       rtc::SSLCertificate** cert);
+  virtual rtc::scoped_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate(
+      const std::string& transport_name);
 
   cricket::DataChannelType data_channel_type() const;
 
diff --git a/webrtc/base/opensslstreamadapter.cc b/webrtc/base/opensslstreamadapter.cc
index 8a3044d..16dd980 100644
--- a/webrtc/base/opensslstreamadapter.cc
+++ b/webrtc/base/opensslstreamadapter.cc
@@ -290,12 +290,11 @@
   role_ = role;
 }
 
-bool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const {
-  if (!peer_certificate_)
-    return false;
-
-  *cert = peer_certificate_->GetReference();
-  return true;
+rtc::scoped_ptr<SSLCertificate> OpenSSLStreamAdapter::GetPeerCertificate()
+    const {
+  return peer_certificate_ ? rtc::scoped_ptr<SSLCertificate>(
+                                 peer_certificate_->GetReference())
+                           : nullptr;
 }
 
 bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
diff --git a/webrtc/base/opensslstreamadapter.h b/webrtc/base/opensslstreamadapter.h
index 231d059..463c8f2 100644
--- a/webrtc/base/opensslstreamadapter.h
+++ b/webrtc/base/opensslstreamadapter.h
@@ -69,7 +69,7 @@
                                 const unsigned char* digest_val,
                                 size_t digest_len) override;
 
-  bool GetPeerCertificate(SSLCertificate** cert) const override;
+  rtc::scoped_ptr<SSLCertificate> GetPeerCertificate() const override;
 
   int StartSSLWithServer(const char* server_name) override;
   int StartSSLWithPeer() override;
diff --git a/webrtc/base/sslstreamadapter.h b/webrtc/base/sslstreamadapter.h
index a50f674..f6f0bef 100644
--- a/webrtc/base/sslstreamadapter.h
+++ b/webrtc/base/sslstreamadapter.h
@@ -154,8 +154,8 @@
 
   // Retrieves the peer's X.509 certificate, if a connection has been
   // established. It returns the transmitted over SSL, including the entire
-  // chain. The returned certificate is owned by the caller.
-  virtual bool GetPeerCertificate(SSLCertificate** cert) const = 0;
+  // chain.
+  virtual rtc::scoped_ptr<SSLCertificate> GetPeerCertificate() const = 0;
 
   // Retrieves the IANA registration id of the cipher suite used for the
   // connection (e.g. 0x2F for "TLS_RSA_WITH_AES_128_CBC_SHA").
diff --git a/webrtc/base/sslstreamadapter_unittest.cc b/webrtc/base/sslstreamadapter_unittest.cc
index 1e18b83..8d5b275 100644
--- a/webrtc/base/sslstreamadapter_unittest.cc
+++ b/webrtc/base/sslstreamadapter_unittest.cc
@@ -474,11 +474,11 @@
       return server_ssl_->GetDtlsSrtpCryptoSuite(retval);
   }
 
-  bool GetPeerCertificate(bool client, rtc::SSLCertificate** cert) {
+  rtc::scoped_ptr<rtc::SSLCertificate> GetPeerCertificate(bool client) {
     if (client)
-      return client_ssl_->GetPeerCertificate(cert);
+      return client_ssl_->GetPeerCertificate();
     else
-      return server_ssl_->GetPeerCertificate(cert);
+      return server_ssl_->GetPeerCertificate();
   }
 
   bool GetSslCipherSuite(bool client, int* retval) {
@@ -1037,19 +1037,15 @@
   MAYBE_SKIP_TEST(HaveDtls);
 
   // Peer certificates haven't been received yet.
-  rtc::scoped_ptr<rtc::SSLCertificate> client_peer_cert;
-  ASSERT_FALSE(GetPeerCertificate(true, client_peer_cert.accept()));
-  ASSERT_FALSE(client_peer_cert != NULL);
-
-  rtc::scoped_ptr<rtc::SSLCertificate> server_peer_cert;
-  ASSERT_FALSE(GetPeerCertificate(false, server_peer_cert.accept()));
-  ASSERT_FALSE(server_peer_cert != NULL);
+  ASSERT_FALSE(GetPeerCertificate(true));
+  ASSERT_FALSE(GetPeerCertificate(false));
 
   TestHandshake();
 
   // The client should have a peer certificate after the handshake.
-  ASSERT_TRUE(GetPeerCertificate(true, client_peer_cert.accept()));
-  ASSERT_TRUE(client_peer_cert != NULL);
+  rtc::scoped_ptr<rtc::SSLCertificate> client_peer_cert =
+      GetPeerCertificate(true);
+  ASSERT_TRUE(client_peer_cert);
 
   // It's not kCERT_PEM.
   std::string client_peer_string = client_peer_cert->ToPEMString();
@@ -1059,8 +1055,9 @@
   ASSERT_FALSE(client_peer_cert->GetChain());
 
   // The server should have a peer certificate after the handshake.
-  ASSERT_TRUE(GetPeerCertificate(false, server_peer_cert.accept()));
-  ASSERT_TRUE(server_peer_cert != NULL);
+  rtc::scoped_ptr<rtc::SSLCertificate> server_peer_cert =
+      GetPeerCertificate(false);
+  ASSERT_TRUE(server_peer_cert);
 
   // It's kCERT_PEM
   ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString());
diff --git a/webrtc/p2p/base/dtlstransportchannel.cc b/webrtc/p2p/base/dtlstransportchannel.cc
index 667b2c8..88a1192 100644
--- a/webrtc/p2p/base/dtlstransportchannel.cc
+++ b/webrtc/p2p/base/dtlstransportchannel.cc
@@ -250,13 +250,13 @@
   return true;
 }
 
-bool DtlsTransportChannelWrapper::GetRemoteSSLCertificate(
-    rtc::SSLCertificate** cert) const {
+rtc::scoped_ptr<rtc::SSLCertificate>
+DtlsTransportChannelWrapper::GetRemoteSSLCertificate() const {
   if (!dtls_) {
-    return false;
+    return nullptr;
   }
 
-  return dtls_->GetPeerCertificate(cert);
+  return dtls_->GetPeerCertificate();
 }
 
 bool DtlsTransportChannelWrapper::SetupDtls() {
diff --git a/webrtc/p2p/base/dtlstransportchannel.h b/webrtc/p2p/base/dtlstransportchannel.h
index 96ea29f..b6c3cfd 100644
--- a/webrtc/p2p/base/dtlstransportchannel.h
+++ b/webrtc/p2p/base/dtlstransportchannel.h
@@ -137,7 +137,7 @@
 
   // Once DTLS has been established, this method retrieves the certificate in
   // use by the remote peer, for use in external identity verification.
-  bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert) const override;
+  rtc::scoped_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate() const override;
 
   // Once DTLS has established (i.e., this channel is writable), this method
   // extracts the keys negotiated during the DTLS handshake, for use in external
diff --git a/webrtc/p2p/base/dtlstransportchannel_unittest.cc b/webrtc/p2p/base/dtlstransportchannel_unittest.cc
index 18b355f..7643016 100644
--- a/webrtc/p2p/base/dtlstransportchannel_unittest.cc
+++ b/webrtc/p2p/base/dtlstransportchannel_unittest.cc
@@ -855,12 +855,8 @@
   ASSERT_TRUE(client2_.transport()->GetLocalCertificate(&certificate2));
   ASSERT_NE(certificate1->ssl_certificate().ToPEMString(),
             certificate2->ssl_certificate().ToPEMString());
-  ASSERT_FALSE(
-      client1_.transport()->GetRemoteSSLCertificate(remote_cert1.accept()));
-  ASSERT_FALSE(remote_cert1 != NULL);
-  ASSERT_FALSE(
-      client2_.transport()->GetRemoteSSLCertificate(remote_cert2.accept()));
-  ASSERT_FALSE(remote_cert2 != NULL);
+  ASSERT_FALSE(client1_.transport()->GetRemoteSSLCertificate());
+  ASSERT_FALSE(client2_.transport()->GetRemoteSSLCertificate());
 }
 
 // Test Certificates state after connection.
@@ -871,8 +867,6 @@
 
   rtc::scoped_refptr<rtc::RTCCertificate> certificate1;
   rtc::scoped_refptr<rtc::RTCCertificate> certificate2;
-  rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1;
-  rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2;
 
   // After connection, each side has a distinct local certificate.
   ASSERT_TRUE(client1_.transport()->GetLocalCertificate(&certificate1));
@@ -881,12 +875,14 @@
             certificate2->ssl_certificate().ToPEMString());
 
   // Each side's remote certificate is the other side's local certificate.
-  ASSERT_TRUE(
-      client1_.transport()->GetRemoteSSLCertificate(remote_cert1.accept()));
+  rtc::scoped_ptr<rtc::SSLCertificate> remote_cert1 =
+      client1_.transport()->GetRemoteSSLCertificate();
+  ASSERT_TRUE(remote_cert1);
   ASSERT_EQ(remote_cert1->ToPEMString(),
             certificate2->ssl_certificate().ToPEMString());
-  ASSERT_TRUE(
-      client2_.transport()->GetRemoteSSLCertificate(remote_cert2.accept()));
+  rtc::scoped_ptr<rtc::SSLCertificate> remote_cert2 =
+      client2_.transport()->GetRemoteSSLCertificate();
+  ASSERT_TRUE(remote_cert2);
   ASSERT_EQ(remote_cert2->ToPEMString(),
             certificate1->ssl_certificate().ToPEMString());
 }
diff --git a/webrtc/p2p/base/faketransportcontroller.h b/webrtc/p2p/base/faketransportcontroller.h
index a267f20..2e0c9a9 100644
--- a/webrtc/p2p/base/faketransportcontroller.h
+++ b/webrtc/p2p/base/faketransportcontroller.h
@@ -260,12 +260,11 @@
     return local_cert_;
   }
 
-  bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert) const override {
-    if (!remote_cert_)
-      return false;
-
-    *cert = remote_cert_->GetReference();
-    return true;
+  rtc::scoped_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate()
+      const override {
+    return remote_cert_ ? rtc::scoped_ptr<rtc::SSLCertificate>(
+                              remote_cert_->GetReference())
+                        : nullptr;
   }
 
   bool ExportKeyingMaterial(const std::string& label,
diff --git a/webrtc/p2p/base/p2ptransportchannel.h b/webrtc/p2p/base/p2ptransportchannel.h
index 5be9d04..4a53d75 100644
--- a/webrtc/p2p/base/p2ptransportchannel.h
+++ b/webrtc/p2p/base/p2ptransportchannel.h
@@ -144,8 +144,9 @@
     return nullptr;
   }
 
-  bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert) const override {
-    return false;
+  rtc::scoped_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate()
+      const override {
+    return nullptr;
   }
 
   // Allows key material to be extracted for external encryption.
diff --git a/webrtc/p2p/base/transport.cc b/webrtc/p2p/base/transport.cc
index b8d9810..a198882 100644
--- a/webrtc/p2p/base/transport.cc
+++ b/webrtc/p2p/base/transport.cc
@@ -77,13 +77,13 @@
   }
 }
 
-bool Transport::GetRemoteSSLCertificate(rtc::SSLCertificate** cert) {
+rtc::scoped_ptr<rtc::SSLCertificate> Transport::GetRemoteSSLCertificate() {
   if (channels_.empty()) {
-    return false;
+    return nullptr;
   }
 
   auto iter = channels_.begin();
-  return iter->second->GetRemoteSSLCertificate(cert);
+  return iter->second->GetRemoteSSLCertificate();
 }
 
 void Transport::SetIceConfig(const IceConfig& config) {
diff --git a/webrtc/p2p/base/transport.h b/webrtc/p2p/base/transport.h
index 66e300a..8b30127 100644
--- a/webrtc/p2p/base/transport.h
+++ b/webrtc/p2p/base/transport.h
@@ -214,7 +214,7 @@
   }
 
   // Get a copy of the remote certificate in use by the specified channel.
-  bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert);
+  rtc::scoped_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate();
 
   // Create, destroy, and lookup the channels of this type by their components.
   TransportChannelImpl* CreateChannel(int component);
diff --git a/webrtc/p2p/base/transportchannel.h b/webrtc/p2p/base/transportchannel.h
index d21d607..24f90e3 100644
--- a/webrtc/p2p/base/transportchannel.h
+++ b/webrtc/p2p/base/transportchannel.h
@@ -129,8 +129,9 @@
   virtual rtc::scoped_refptr<rtc::RTCCertificate>
   GetLocalCertificate() const = 0;
 
-  // Gets a copy of the remote side's SSL certificate, owned by the caller.
-  virtual bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert) const = 0;
+  // Gets a copy of the remote side's SSL certificate.
+  virtual rtc::scoped_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate()
+      const = 0;
 
   // Allows key material to be extracted for external encryption.
   virtual bool ExportKeyingMaterial(const std::string& label,
diff --git a/webrtc/p2p/base/transportcontroller.cc b/webrtc/p2p/base/transportcontroller.cc
index 128d2fc..708c60f 100644
--- a/webrtc/p2p/base/transportcontroller.cc
+++ b/webrtc/p2p/base/transportcontroller.cc
@@ -86,12 +86,11 @@
                 transport_name, certificate));
 }
 
-bool TransportController::GetRemoteSSLCertificate(
-    const std::string& transport_name,
-    rtc::SSLCertificate** cert) {
-  return worker_thread_->Invoke<bool>(
-      rtc::Bind(&TransportController::GetRemoteSSLCertificate_w, this,
-                transport_name, cert));
+rtc::scoped_ptr<rtc::SSLCertificate>
+TransportController::GetRemoteSSLCertificate(
+    const std::string& transport_name) {
+  return worker_thread_->Invoke<rtc::scoped_ptr<rtc::SSLCertificate>>(rtc::Bind(
+      &TransportController::GetRemoteSSLCertificate_w, this, transport_name));
 }
 
 bool TransportController::SetLocalTransportDescription(
@@ -395,17 +394,17 @@
   return t->GetLocalCertificate(certificate);
 }
 
-bool TransportController::GetRemoteSSLCertificate_w(
-    const std::string& transport_name,
-    rtc::SSLCertificate** cert) {
+rtc::scoped_ptr<rtc::SSLCertificate>
+TransportController::GetRemoteSSLCertificate_w(
+    const std::string& transport_name) {
   RTC_DCHECK(worker_thread_->IsCurrent());
 
   Transport* t = GetTransport_w(transport_name);
   if (!t) {
-    return false;
+    return nullptr;
   }
 
-  return t->GetRemoteSSLCertificate(cert);
+  return t->GetRemoteSSLCertificate();
 }
 
 bool TransportController::SetLocalTransportDescription_w(
diff --git a/webrtc/p2p/base/transportcontroller.h b/webrtc/p2p/base/transportcontroller.h
index ed72160..9d06823 100644
--- a/webrtc/p2p/base/transportcontroller.h
+++ b/webrtc/p2p/base/transportcontroller.h
@@ -59,8 +59,8 @@
       const std::string& transport_name,
       rtc::scoped_refptr<rtc::RTCCertificate>* certificate);
   // Caller owns returned certificate
-  bool GetRemoteSSLCertificate(const std::string& transport_name,
-                               rtc::SSLCertificate** cert);
+  rtc::scoped_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate(
+      const std::string& transport_name);
   bool SetLocalTransportDescription(const std::string& transport_name,
                                     const TransportDescription& tdesc,
                                     ContentAction action,
@@ -166,8 +166,8 @@
   bool GetLocalCertificate_w(
       const std::string& transport_name,
       rtc::scoped_refptr<rtc::RTCCertificate>* certificate);
-  bool GetRemoteSSLCertificate_w(const std::string& transport_name,
-                                 rtc::SSLCertificate** cert);
+  rtc::scoped_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate_w(
+      const std::string& transport_name);
   bool SetLocalTransportDescription_w(const std::string& transport_name,
                                       const TransportDescription& tdesc,
                                       ContentAction action,
diff --git a/webrtc/p2p/base/transportcontroller_unittest.cc b/webrtc/p2p/base/transportcontroller_unittest.cc
index 4016273..c90fd70 100644
--- a/webrtc/p2p/base/transportcontroller_unittest.cc
+++ b/webrtc/p2p/base/transportcontroller_unittest.cc
@@ -303,20 +303,19 @@
 
 TEST_F(TransportControllerTest, TestGetRemoteSSLCertificate) {
   rtc::FakeSSLCertificate fake_certificate("fake_data");
-  rtc::scoped_ptr<rtc::SSLCertificate> returned_certificate;
 
   FakeTransportChannel* channel = CreateChannel("audio", 1);
   ASSERT_NE(nullptr, channel);
 
   channel->SetRemoteSSLCertificate(&fake_certificate);
-  EXPECT_TRUE(transport_controller_->GetRemoteSSLCertificate(
-      "audio", returned_certificate.accept()));
+  rtc::scoped_ptr<rtc::SSLCertificate> returned_certificate =
+      transport_controller_->GetRemoteSSLCertificate("audio");
+  EXPECT_TRUE(returned_certificate);
   EXPECT_EQ(fake_certificate.ToPEMString(),
             returned_certificate->ToPEMString());
 
   // Should fail if called for a nonexistant transport.
-  EXPECT_FALSE(transport_controller_->GetRemoteSSLCertificate(
-      "video", returned_certificate.accept()));
+  EXPECT_FALSE(transport_controller_->GetRemoteSSLCertificate("video"));
 }
 
 TEST_F(TransportControllerTest, TestSetLocalTransportDescription) {