Replaces SSLIdentity* with scoped_refptr<RTCCertificate> in the cricket::Transport layer.

Why the replacements? Mainly two reasons:
1) RTCCertificate owns the identity and as long as things are referencing the identity there should be a scoped_refptr reference to the RTCCertificate. Handing out raw pointers is less memory safe.
2) With the latest RFC, an RTCCertificate should be sufficient for specifying a crypto cert and the code should be updated to use RTCCertificate instead of SSLIdentity directly.

This replace work is split up into multiple CLs. In this CL...
- WebRtcSessionDescriptionFactory is updated to use RTCCertificate over SSLIdentity.
- WebRtcSessionDescriptionFactory::SignalCertificateReady is connected to WebRtcSession::OnCertificateReady and WebRtcSession is updated to use RTCCertificate.
- The cricket::Transport and related classes are updated to use RTCCertificate. These are called from WebRtcSession::OnCertificateReady.

BUG=webrtc:4927
R=tommi@webrtc.org, torbjorng@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#9794}
diff --git a/talk/app/webrtc/statscollector.cc b/talk/app/webrtc/statscollector.cc
index ad64639..eb32356 100644
--- a/talk/app/webrtc/statscollector.cc
+++ b/talk/app/webrtc/statscollector.cc
@@ -692,7 +692,7 @@
     // expose them in stats reports.  All channels in a transport share the
     // same local and remote certificates.
     //
-    // Note that Transport::GetIdentity and Transport::GetRemoteCertificate
+    // Note that Transport::GetCertificate and Transport::GetRemoteCertificate
     // invoke method calls on the worker thread and block this thread, but
     // messages are still processed on this thread, which may blow way the
     // existing transports. So we cannot reuse |transport| after these calls.
@@ -700,9 +700,9 @@
 
     cricket::Transport* transport =
         session_->GetTransport(transport_iter.second.content_name);
-    rtc::scoped_ptr<rtc::SSLIdentity> identity;
-    if (transport && transport->GetIdentity(identity.accept())) {
-      StatsReport* r = AddCertificateReports(&(identity->certificate()));
+    rtc::scoped_refptr<rtc::RTCCertificate> certificate;
+    if (transport && transport->GetCertificate(&certificate)) {
+      StatsReport* r = AddCertificateReports(&(certificate->ssl_certificate()));
       if (r)
         local_cert_report_id = r->id();
     }
diff --git a/talk/app/webrtc/statscollector_unittest.cc b/talk/app/webrtc/statscollector_unittest.cc
index ab9181f..fd1ad61 100644
--- a/talk/app/webrtc/statscollector_unittest.cc
+++ b/talk/app/webrtc/statscollector_unittest.cc
@@ -656,7 +656,9 @@
         transport_stats;
 
     // Fake certificates to report.
-    rtc::FakeSSLIdentity local_identity(local_cert);
+    rtc::scoped_refptr<rtc::RTCCertificate> local_certificate(
+        rtc::RTCCertificate::Create(rtc::scoped_ptr<rtc::FakeSSLIdentity>(
+            new rtc::FakeSSLIdentity(local_cert)).Pass()));
     rtc::scoped_ptr<rtc::FakeSSLCertificate> remote_cert_copy(
         remote_cert.GetReference());
 
@@ -666,7 +668,7 @@
             session_.signaling_thread(),
             session_.worker_thread(),
             transport_stats.content_name));
-    transport->SetIdentity(&local_identity);
+    transport->SetCertificate(local_certificate);
     cricket::FakeTransportChannel* channel =
         static_cast<cricket::FakeTransportChannel*>(
             transport->CreateChannel(channel_stats.component));
diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc
index 3d192c2..f73cf39 100644
--- a/talk/app/webrtc/webrtcsession.cc
+++ b/talk/app/webrtc/webrtcsession.cc
@@ -564,7 +564,6 @@
   for (size_t i = 0; i < saved_candidates_.size(); ++i) {
     delete saved_candidates_[i];
   }
-  delete identity();
 }
 
 bool WebRtcSession::Initialize(
@@ -751,8 +750,8 @@
     }
   }
 
-  webrtc_session_desc_factory_->SignalIdentityReady.connect(
-      this, &WebRtcSession::OnIdentityReady);
+  webrtc_session_desc_factory_->SignalCertificateReady.connect(
+      this, &WebRtcSession::OnCertificateReady);
 
   if (options.disable_encryption) {
     webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED);
@@ -1392,11 +1391,12 @@
   ice_restart_latch_->Reset();
 }
 
-void WebRtcSession::OnIdentityReady(rtc::SSLIdentity* identity) {
-  SetIdentity(identity);
+void WebRtcSession::OnCertificateReady(
+    const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
+  SetCertificate(certificate);
 }
 
-bool WebRtcSession::waiting_for_identity_for_testing() const {
+bool WebRtcSession::waiting_for_certificate_for_testing() const {
   return webrtc_session_desc_factory_->waiting_for_certificate_for_testing();
 }
 
diff --git a/talk/app/webrtc/webrtcsession.h b/talk/app/webrtc/webrtcsession.h
index b580d34..bb405c5 100644
--- a/talk/app/webrtc/webrtcsession.h
+++ b/talk/app/webrtc/webrtcsession.h
@@ -246,13 +246,14 @@
 
   void ResetIceRestartLatch();
 
-  // Called when an SSLIdentity is generated or retrieved by
+  // Called when an RTCCertificate is generated or retrieved by
   // WebRTCSessionDescriptionFactory. Should happen before setLocalDescription.
-  void OnIdentityReady(rtc::SSLIdentity* identity);
+  void OnCertificateReady(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
   void OnDtlsSetupFailure(cricket::BaseChannel*, bool rtcp);
 
   // For unit test.
-  bool waiting_for_identity_for_testing() const;
+  bool waiting_for_certificate_for_testing() const;
 
   void set_metrics_observer(
       webrtc::MetricsObserverInterface* metrics_observer) {
diff --git a/talk/app/webrtc/webrtcsession_unittest.cc b/talk/app/webrtc/webrtcsession_unittest.cc
index a23130d..2c52d13 100644
--- a/talk/app/webrtc/webrtcsession_unittest.cc
+++ b/talk/app/webrtc/webrtcsession_unittest.cc
@@ -3575,20 +3575,17 @@
   EXPECT_EQ(new_recv_port, portnum);
 }
 
-// TODO(hbos): Add the following test once RTCCertificate is passed around
-// outside of WebRtcSessionDescriptionFactory code and there exists a
-// WebRtcSession::certificate().
-//TEST_F(WebRtcSessionTest, TestUsesProvidedCertificate) {
-//  rtc::scoped_refptr<rtc::RTCCertificate> certificate =
-//      FakeDtlsIdentityStore::GenerateCertificate();
-//
-//  PeerConnectionInterface::RTCConfiguration configuration;
-//  configuration.certificates.push_back(certificate);
-//  Init(nullptr, configuration);
-//  EXPECT_TRUE_WAIT(!session_->waiting_for_identity_for_testing(), 1000);
-//
-//  EXPECT_EQ(session_->certificate(), certificate);
-//}
+TEST_F(WebRtcSessionTest, TestUsesProvidedCertificate) {
+  rtc::scoped_refptr<rtc::RTCCertificate> certificate =
+      FakeDtlsIdentityStore::GenerateCertificate();
+
+  PeerConnectionInterface::RTCConfiguration configuration;
+  configuration.certificates.push_back(certificate);
+  Init(nullptr, configuration);
+  EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
+
+  EXPECT_EQ(session_->certificate_for_testing(), certificate);
+}
 
 // Verifies that CreateOffer succeeds when CreateOffer is called before async
 // identity generation is finished (even if a certificate is provided this is
@@ -3597,7 +3594,7 @@
   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   InitWithDtls(GetParam());
 
-  EXPECT_TRUE(session_->waiting_for_identity_for_testing());
+  EXPECT_TRUE(session_->waiting_for_certificate_for_testing());
   mediastream_signaling_.SendAudioVideoStream1();
   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
 
@@ -3634,7 +3631,7 @@
   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   InitWithDtls(GetParam());
 
-  EXPECT_TRUE_WAIT(!session_->waiting_for_identity_for_testing(), 1000);
+  EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
 
   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   EXPECT_TRUE(offer != NULL);
@@ -3646,7 +3643,7 @@
   MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
   InitWithDtlsIdentityGenFail();
 
-  EXPECT_TRUE_WAIT(!session_->waiting_for_identity_for_testing(), 1000);
+  EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
 
   rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
   EXPECT_TRUE(offer == NULL);
diff --git a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
index 4336372..41bcfa0 100644
--- a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
+++ b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
@@ -98,14 +98,14 @@
       rtc::kPemTypeRsaPrivateKey,
       reinterpret_cast<const unsigned char*>(der_private_key.data()),
       der_private_key.length());
-  rtc::SSLIdentity* identity =
-      rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert);
-  SignalIdentityReady(identity);
+  rtc::scoped_ptr<rtc::SSLIdentity> identity(
+      rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert));
+  SignalCertificateReady(rtc::RTCCertificate::Create(identity.Pass()));
 }
 
 void WebRtcIdentityRequestObserver::OnSuccess(
     rtc::scoped_ptr<rtc::SSLIdentity> identity) {
-  SignalIdentityReady(identity.release());
+  SignalCertificateReady(rtc::RTCCertificate::Create(identity.Pass()));
 }
 
 // static
@@ -195,8 +195,8 @@
 
   identity_request_observer_->SignalRequestFailed.connect(
       this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed);
-  identity_request_observer_->SignalIdentityReady.connect(
-      this, &WebRtcSessionDescriptionFactory::SetIdentity);
+  identity_request_observer_->SignalCertificateReady.connect(
+      this, &WebRtcSessionDescriptionFactory::SetCertificate);
 
   rtc::KeyType key_type = rtc::KT_DEFAULT;
   LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sending DTLS identity request (key "
@@ -387,9 +387,7 @@
           static_cast<rtc::ScopedRefMessageData<rtc::RTCCertificate>*>(
               msg->pdata);
       LOG(LS_INFO) << "Using certificate supplied to the constructor.";
-      // TODO(hbos): Pass around scoped_refptr<RTCCertificate> instead of
-      // SSLIdentity* (then there will be no need to do GetReference here).
-      SetIdentity(param->data()->identity()->GetReference());
+      SetCertificate(param->data());
       delete param;
       break;
     }
@@ -516,14 +514,16 @@
   FailPendingRequests(kFailedDueToIdentityFailed);
 }
 
-void WebRtcSessionDescriptionFactory::SetIdentity(
-    rtc::SSLIdentity* identity) {
-  LOG(LS_VERBOSE) << "Setting new identity";
+void WebRtcSessionDescriptionFactory::SetCertificate(
+    const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
+  DCHECK(certificate);
+  LOG(LS_VERBOSE) << "Setting new certificate";
 
   certificate_request_state_ = CERTIFICATE_SUCCEEDED;
-  SignalIdentityReady(identity);
+  SignalCertificateReady(certificate);
 
-  transport_desc_factory_.set_identity(identity);
+  // TODO(hbos): set_certificate
+  transport_desc_factory_.set_identity(certificate->identity());
   transport_desc_factory_.set_secure(cricket::SEC_ENABLED);
 
   while (!create_session_description_requests_.empty()) {
diff --git a/talk/app/webrtc/webrtcsessiondescriptionfactory.h b/talk/app/webrtc/webrtcsessiondescriptionfactory.h
index 8ba0ac2..8abf6aa 100644
--- a/talk/app/webrtc/webrtcsessiondescriptionfactory.h
+++ b/talk/app/webrtc/webrtcsessiondescriptionfactory.h
@@ -58,7 +58,8 @@
   void OnSuccess(rtc::scoped_ptr<rtc::SSLIdentity> identity) override;
 
   sigslot::signal1<int> SignalRequestFailed;
-  sigslot::signal1<rtc::SSLIdentity*> SignalIdentityReady;
+  sigslot::signal1<const rtc::scoped_refptr<rtc::RTCCertificate>&>
+      SignalCertificateReady;
 };
 
 struct CreateSessionDescriptionRequest {
@@ -134,7 +135,8 @@
   void SetSdesPolicy(cricket::SecurePolicy secure_policy);
   cricket::SecurePolicy SdesPolicy() const;
 
-  sigslot::signal1<rtc::SSLIdentity*> SignalIdentityReady;
+  sigslot::signal1<const rtc::scoped_refptr<rtc::RTCCertificate>&>
+      SignalCertificateReady;
 
   // For testing.
   bool waiting_for_certificate_for_testing() const {
@@ -176,7 +178,8 @@
       SessionDescriptionInterface* description);
 
   void OnIdentityRequestFailed(int error);
-  void SetIdentity(rtc::SSLIdentity* identity);
+  void SetCertificate(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
 
   std::queue<CreateSessionDescriptionRequest>
       create_session_description_requests_;
diff --git a/talk/session/media/channel_unittest.cc b/talk/session/media/channel_unittest.cc
index a793028..03f33a4 100644
--- a/talk/session/media/channel_unittest.cc
+++ b/talk/session/media/channel_unittest.cc
@@ -196,13 +196,15 @@
 
     if (flags1 & DTLS) {
       // Confirmed to work with KT_RSA and KT_ECDSA.
-      identity1_.reset(rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT));
-      session1_.set_ssl_identity(identity1_.get());
+      session1_.set_ssl_rtccertificate(rtc::RTCCertificate::Create(
+          rtc::scoped_ptr<rtc::SSLIdentity>(rtc::SSLIdentity::Generate(
+              "session1", rtc::KT_DEFAULT)).Pass()));
     }
     if (flags2 & DTLS) {
       // Confirmed to work with KT_RSA and KT_ECDSA.
-      identity2_.reset(rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT));
-      session2_.set_ssl_identity(identity2_.get());
+      session2_.set_ssl_rtccertificate(rtc::RTCCertificate::Create(
+          rtc::scoped_ptr<rtc::SSLIdentity>(rtc::SSLIdentity::Generate(
+              "session2", rtc::KT_DEFAULT)).Pass()));
     }
 
     // Add stream information (SSRC) to the local content but not to the remote
@@ -1791,8 +1793,6 @@
   typename T::Content local_media_content2_;
   typename T::Content remote_media_content1_;
   typename T::Content remote_media_content2_;
-  rtc::scoped_ptr<rtc::SSLIdentity> identity1_;
-  rtc::scoped_ptr<rtc::SSLIdentity> identity2_;
   // The RTP and RTCP packets to send in the tests.
   std::string rtp_packet_;
   std::string rtcp_packet_;
diff --git a/webrtc/p2p/base/dtlstransport.h b/webrtc/p2p/base/dtlstransport.h
index 27cece4..0c53ff9 100644
--- a/webrtc/p2p/base/dtlstransport.h
+++ b/webrtc/p2p/base/dtlstransport.h
@@ -11,6 +11,7 @@
 #ifndef WEBRTC_P2P_BASE_DTLSTRANSPORT_H_
 #define WEBRTC_P2P_BASE_DTLSTRANSPORT_H_
 
+#include "webrtc/base/checks.h"
 #include "webrtc/p2p/base/dtlstransportchannel.h"
 #include "webrtc/p2p/base/transport.h"
 
@@ -23,6 +24,7 @@
 class PortAllocator;
 
 // Base should be a descendant of cricket::Transport
+// TODO(hbos): Add appropriate DCHECK thread checks to all methods.
 template<class Base>
 class DtlsTransport : public Base {
  public:
@@ -30,9 +32,9 @@
                 rtc::Thread* worker_thread,
                 const std::string& content_name,
                 PortAllocator* allocator,
-                rtc::SSLIdentity* identity)
+                const rtc::scoped_refptr<rtc::RTCCertificate>& certificate)
       : Base(signaling_thread, worker_thread, content_name, allocator),
-        identity_(identity),
+        certificate_(certificate),
         secure_role_(rtc::SSL_CLIENT),
         ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10) {
   }
@@ -40,33 +42,39 @@
   ~DtlsTransport() {
     Base::DestroyAllChannels();
   }
-  virtual void SetIdentity_w(rtc::SSLIdentity* identity) {
-    identity_ = identity;
+  void SetCertificate_w(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
+    DCHECK(Base::worker_thread()->IsCurrent());
+    certificate_ = certificate;
   }
-  virtual bool GetIdentity_w(rtc::SSLIdentity** identity) {
-    if (!identity_)
+  bool GetCertificate_w(
+      rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
+    DCHECK(Base::worker_thread()->IsCurrent());
+    if (!certificate_)
       return false;
 
-    *identity = identity_->GetReference();
+    *certificate = certificate_;
     return true;
   }
 
   virtual bool SetSslMaxProtocolVersion_w(rtc::SSLProtocolVersion version) {
+    DCHECK(Base::worker_thread()->IsCurrent());
     ssl_max_version_ = version;
     return true;
   }
 
   virtual bool ApplyLocalTransportDescription_w(TransportChannelImpl* channel,
                                                 std::string* error_desc) {
+    DCHECK(Base::worker_thread()->IsCurrent());
     rtc::SSLFingerprint* local_fp =
         Base::local_description()->identity_fingerprint.get();
 
     if (local_fp) {
       // Sanity check local fingerprint.
-      if (identity_) {
+      if (certificate_) {
         rtc::scoped_ptr<rtc::SSLFingerprint> local_fp_tmp(
             rtc::SSLFingerprint::Create(local_fp->algorithm,
-                                              identity_));
+                                        certificate_->identity()));
         ASSERT(local_fp_tmp.get() != NULL);
         if (!(*local_fp_tmp == *local_fp)) {
           std::ostringstream desc;
@@ -81,10 +89,12 @@
             error_desc);
       }
     } else {
-      identity_ = NULL;
+      certificate_ = nullptr;
     }
 
-    if (!channel->SetLocalIdentity(identity_)) {
+    // TODO(hbos): SetLocalCertificate
+    if (!channel->SetLocalIdentity(
+        certificate_ ? certificate_->identity() : nullptr)) {
       return BadTransportDescription("Failed to set local identity.",
                                      error_desc);
     }
@@ -95,6 +105,7 @@
 
   virtual bool NegotiateTransportDescription_w(ContentAction local_role,
                                                std::string* error_desc) {
+    DCHECK(Base::worker_thread()->IsCurrent());
     if (!Base::local_description() || !Base::remote_description()) {
       const std::string msg = "Local and Remote description must be set before "
                               "transport descriptions are negotiated";
@@ -211,6 +222,7 @@
   }
 
   virtual bool GetSslRole_w(rtc::SSLRole* ssl_role) const {
+    DCHECK(Base::worker_thread()->IsCurrent());
     ASSERT(ssl_role != NULL);
     *ssl_role = secure_role_;
     return true;
@@ -220,6 +232,7 @@
   virtual bool ApplyNegotiatedTransportDescription_w(
       TransportChannelImpl* channel,
       std::string* error_desc) {
+    DCHECK(Base::worker_thread()->IsCurrent());
     // Set ssl role. Role must be set before fingerprint is applied, which
     // initiates DTLS setup.
     if (!channel->SetSslRole(secure_role_)) {
@@ -237,7 +250,7 @@
     return Base::ApplyNegotiatedTransportDescription_w(channel, error_desc);
   }
 
-  rtc::SSLIdentity* identity_;
+  rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
   rtc::SSLRole secure_role_;
   rtc::SSLProtocolVersion ssl_max_version_;
   rtc::scoped_ptr<rtc::SSLFingerprint> remote_fingerprint_;
diff --git a/webrtc/p2p/base/dtlstransportchannel_unittest.cc b/webrtc/p2p/base/dtlstransportchannel_unittest.cc
index 26f6578..34aa651 100644
--- a/webrtc/p2p/base/dtlstransportchannel_unittest.cc
+++ b/webrtc/p2p/base/dtlstransportchannel_unittest.cc
@@ -58,12 +58,16 @@
       received_dtls_client_hello_(false),
       received_dtls_server_hello_(false) {
   }
-  void CreateIdentity(rtc::KeyType key_type) {
-    identity_.reset(rtc::SSLIdentity::Generate(name_, key_type));
+  void CreateCertificate(rtc::KeyType key_type) {
+    certificate_ = rtc::RTCCertificate::Create(
+        rtc::scoped_ptr<rtc::SSLIdentity>(
+            rtc::SSLIdentity::Generate(name_, key_type)).Pass());
   }
-  rtc::SSLIdentity* identity() { return identity_.get(); }
+  const rtc::scoped_refptr<rtc::RTCCertificate>& certificate() {
+    return certificate_;
+  }
   void SetupSrtp() {
-    ASSERT(identity_.get() != NULL);
+    ASSERT(certificate_);
     use_dtls_srtp_ = true;
   }
   void SetupMaxProtocolVersion(rtc::SSLProtocolVersion version) {
@@ -72,8 +76,8 @@
   }
   void SetupChannels(int count, cricket::IceRole role) {
     transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>(
-        signaling_thread_, worker_thread_, "dtls content name", NULL,
-        identity_.get()));
+        signaling_thread_, worker_thread_, "dtls content name", nullptr,
+        certificate_));
     transport_->SetAsync(true);
     transport_->SetIceRole(role);
     transport_->SetIceTiebreaker(
@@ -114,36 +118,36 @@
   void Negotiate(DtlsTestClient* peer, cricket::ContentAction action,
                  ConnectionRole local_role, ConnectionRole remote_role,
                  int flags) {
-    Negotiate(identity_.get(), (identity_) ? peer->identity_.get() : NULL,
+    Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr,
               action, local_role, remote_role, flags);
   }
 
   // Allow any DTLS configuration to be specified (including invalid ones).
-  void Negotiate(rtc::SSLIdentity* local_identity,
-                 rtc::SSLIdentity* remote_identity,
+  void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert,
+                 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert,
                  cricket::ContentAction action,
                  ConnectionRole local_role,
                  ConnectionRole remote_role,
                  int flags) {
     rtc::scoped_ptr<rtc::SSLFingerprint> local_fingerprint;
     rtc::scoped_ptr<rtc::SSLFingerprint> remote_fingerprint;
-    if (local_identity) {
+    if (local_cert) {
       std::string digest_algorithm;
-      ASSERT_TRUE(local_identity->certificate().GetSignatureDigestAlgorithm(
+      ASSERT_TRUE(local_cert->ssl_certificate().GetSignatureDigestAlgorithm(
           &digest_algorithm));
       ASSERT_FALSE(digest_algorithm.empty());
       local_fingerprint.reset(rtc::SSLFingerprint::Create(
-          digest_algorithm, local_identity));
+          digest_algorithm, local_cert->identity()));
       ASSERT_TRUE(local_fingerprint.get() != NULL);
       EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm);
     }
-    if (remote_identity) {
+    if (remote_cert) {
       std::string digest_algorithm;
-      ASSERT_TRUE(remote_identity->certificate().GetSignatureDigestAlgorithm(
+      ASSERT_TRUE(remote_cert->ssl_certificate().GetSignatureDigestAlgorithm(
           &digest_algorithm));
       ASSERT_FALSE(digest_algorithm.empty());
       remote_fingerprint.reset(rtc::SSLFingerprint::Create(
-          digest_algorithm, remote_identity));
+          digest_algorithm, remote_cert->identity()));
       ASSERT_TRUE(remote_fingerprint.get() != NULL);
       EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm);
     }
@@ -163,7 +167,7 @@
         cricket::ICEMODE_FULL, local_role,
          // If remote if the offerer and has no DTLS support, answer will be
         // without any fingerprint.
-        (action == cricket::CA_ANSWER && !remote_identity) ?
+        (action == cricket::CA_ANSWER && !remote_cert) ?
             NULL : local_fingerprint.get(),
         cricket::Candidates());
 
@@ -186,7 +190,7 @@
       ASSERT_EQ(expect_success, transport_->SetLocalTransportDescription(
           local_desc, cricket::CA_ANSWER, NULL));
     }
-    negotiated_dtls_ = (local_identity && remote_identity);
+    negotiated_dtls_ = (local_cert && remote_cert);
   }
 
   bool Connect(DtlsTestClient* peer) {
@@ -252,7 +256,7 @@
                          static_cast<uint32>(sent));
 
       // Only set the bypass flag if we've activated DTLS.
-      int flags = (identity_.get() && srtp) ? cricket::PF_SRTP_BYPASS : 0;
+      int flags = (certificate_ && srtp) ? cricket::PF_SRTP_BYPASS : 0;
       rtc::PacketOptions packet_options;
       int rv = channels_[channel]->SendPacket(
           packet.get(), size, packet_options, flags);
@@ -333,7 +337,7 @@
     ASSERT_TRUE(VerifyPacket(data, size, &packet_num));
     received_.insert(packet_num);
     // Only DTLS-SRTP packets should have the bypass flag set.
-    int expected_flags = (identity_.get() && IsRtpLeadByte(data[0])) ?
+    int expected_flags = (certificate_ && IsRtpLeadByte(data[0])) ?
         cricket::PF_SRTP_BYPASS : 0;
     ASSERT_EQ(expected_flags, flags);
   }
@@ -370,7 +374,7 @@
   std::string name_;
   rtc::Thread* signaling_thread_;
   rtc::Thread* worker_thread_;
-  rtc::scoped_ptr<rtc::SSLIdentity> identity_;
+  rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
   rtc::scoped_ptr<cricket::FakeTransport> transport_;
   std::vector<cricket::DtlsTransportChannelWrapper*> channels_;
   size_t packet_size_;
@@ -407,10 +411,10 @@
   }
   void PrepareDtls(bool c1, bool c2, rtc::KeyType key_type) {
     if (c1) {
-      client1_.CreateIdentity(key_type);
+      client1_.CreateCertificate(key_type);
     }
     if (c2) {
-      client2_.CreateIdentity(key_type);
+      client2_.CreateCertificate(key_type);
     }
     if (c1 && c2)
       use_dtls_ = true;
@@ -826,17 +830,17 @@
   PrepareDtls(true, true, rtc::KT_DEFAULT);
   Negotiate();
 
-  rtc::scoped_ptr<rtc::SSLIdentity> identity1;
-  rtc::scoped_ptr<rtc::SSLIdentity> identity2;
+  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 negotiation, each side has a distinct local certificate, but still no
   // remote certificate, because connection has not yet occurred.
-  ASSERT_TRUE(client1_.transport()->GetIdentity(identity1.accept()));
-  ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept()));
-  ASSERT_NE(identity1->certificate().ToPEMString(),
-            identity2->certificate().ToPEMString());
+  ASSERT_TRUE(client1_.transport()->GetCertificate(&certificate1));
+  ASSERT_TRUE(client2_.transport()->GetCertificate(&certificate2));
+  ASSERT_NE(certificate1->ssl_certificate().ToPEMString(),
+            certificate2->ssl_certificate().ToPEMString());
   ASSERT_FALSE(
       client1_.transport()->GetRemoteCertificate(remote_cert1.accept()));
   ASSERT_FALSE(remote_cert1 != NULL);
@@ -851,24 +855,24 @@
   PrepareDtls(true, true, rtc::KT_DEFAULT);
   ASSERT_TRUE(Connect());
 
-  rtc::scoped_ptr<rtc::SSLIdentity> identity1;
-  rtc::scoped_ptr<rtc::SSLIdentity> identity2;
+  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()->GetIdentity(identity1.accept()));
-  ASSERT_TRUE(client2_.transport()->GetIdentity(identity2.accept()));
-  ASSERT_NE(identity1->certificate().ToPEMString(),
-            identity2->certificate().ToPEMString());
+  ASSERT_TRUE(client1_.transport()->GetCertificate(&certificate1));
+  ASSERT_TRUE(client2_.transport()->GetCertificate(&certificate2));
+  ASSERT_NE(certificate1->ssl_certificate().ToPEMString(),
+            certificate2->ssl_certificate().ToPEMString());
 
   // Each side's remote certificate is the other side's local certificate.
   ASSERT_TRUE(
       client1_.transport()->GetRemoteCertificate(remote_cert1.accept()));
   ASSERT_EQ(remote_cert1->ToPEMString(),
-            identity2->certificate().ToPEMString());
+            certificate2->ssl_certificate().ToPEMString());
   ASSERT_TRUE(
       client2_.transport()->GetRemoteCertificate(remote_cert2.accept()));
   ASSERT_EQ(remote_cert2->ToPEMString(),
-            identity1->certificate().ToPEMString());
+            certificate1->ssl_certificate().ToPEMString());
 }
diff --git a/webrtc/p2p/base/fakesession.h b/webrtc/p2p/base/fakesession.h
index b63958e..5597a44 100644
--- a/webrtc/p2p/base/fakesession.h
+++ b/webrtc/p2p/base/fakesession.h
@@ -38,6 +38,7 @@
 // Fake transport channel class, which can be passed to anything that needs a
 // transport channel. Can be informed of another FakeTransportChannel via
 // SetDestination.
+// TODO(hbos): Move implementation to .cc file, this and other classes in file.
 class FakeTransportChannel : public TransportChannelImpl,
                              public rtc::MessageHandler {
  public:
@@ -332,12 +333,11 @@
   FakeTransport(rtc::Thread* signaling_thread,
                 rtc::Thread* worker_thread,
                 const std::string& content_name,
-                PortAllocator* alllocator = NULL)
+                PortAllocator* alllocator = nullptr)
       : Transport(signaling_thread, worker_thread,
-                  content_name, NULL),
-      dest_(NULL),
-      async_(false),
-      identity_(NULL) {
+                  content_name, nullptr),
+        dest_(nullptr),
+        async_(false) {
   }
   ~FakeTransport() {
     DestroyAllChannels();
@@ -350,7 +350,9 @@
     dest_ = dest;
     for (ChannelMap::iterator it = channels_.begin(); it != channels_.end();
          ++it) {
-      it->second->SetLocalIdentity(identity_);
+      // TODO(hbos): SetLocalCertificate
+      it->second->SetLocalIdentity(
+          certificate_ ? certificate_->identity() : nullptr);
       SetChannelDestination(it->first, it->second);
     }
   }
@@ -362,8 +364,9 @@
     }
   }
 
-  void set_identity(rtc::SSLIdentity* identity) {
-    identity_ = identity;
+  void set_certificate(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
+    certificate_ = certificate;
   }
 
   using Transport::local_description;
@@ -385,14 +388,16 @@
     channels_.erase(channel->component());
     delete channel;
   }
-  virtual void SetIdentity_w(rtc::SSLIdentity* identity) {
-    identity_ = identity;
+  void SetCertificate_w(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
+    certificate_ = certificate;
   }
-  virtual bool GetIdentity_w(rtc::SSLIdentity** identity) {
-    if (!identity_)
+  bool GetCertificate_w(
+      rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
+    if (!certificate_)
       return false;
 
-    *identity = identity_->GetReference();
+    *certificate = certificate_;
     return true;
   }
 
@@ -407,7 +412,9 @@
     if (dest_) {
       dest_channel = dest_->GetFakeChannel(component);
       if (dest_channel) {
-        dest_channel->SetLocalIdentity(dest_->identity_);
+        // TODO(hbos): SetLocalCertificate
+        dest_channel->SetLocalIdentity(
+            dest_->certificate_ ? dest_->certificate_->identity() : nullptr);
       }
     }
     channel->SetDestination(dest_channel);
@@ -418,7 +425,7 @@
   ChannelMap channels_;
   FakeTransport* dest_;
   bool async_;
-  rtc::SSLIdentity* identity_;
+  rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
 };
 
 // Fake session class, which can be passed into a BaseChannel object for
@@ -474,13 +481,14 @@
   }
 
   // TODO: Hoist this into Session when we re-work the Session code.
-  void set_ssl_identity(rtc::SSLIdentity* identity) {
+  void set_ssl_rtccertificate(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
     for (TransportMap::const_iterator it = transport_proxies().begin();
         it != transport_proxies().end(); ++it) {
       // We know that we have a FakeTransport*
 
-      static_cast<FakeTransport*>(it->second->impl())->set_identity
-          (identity);
+      static_cast<FakeTransport*>(it->second->impl())->set_certificate
+          (certificate);
     }
   }
 
diff --git a/webrtc/p2p/base/session.cc b/webrtc/p2p/base/session.cc
index 6c18511..23680b9 100644
--- a/webrtc/p2p/base/session.cc
+++ b/webrtc/p2p/base/session.cc
@@ -277,9 +277,9 @@
   return true;
 }
 
-void TransportProxy::SetIdentity(
-    rtc::SSLIdentity* identity) {
-  transport_->get()->SetIdentity(identity);
+void TransportProxy::SetCertificate(
+    const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
+  transport_->get()->SetCertificate(certificate);
 }
 
 std::string BaseSession::StateToString(State state) {
@@ -336,7 +336,6 @@
       sid_(sid),
       content_type_(content_type),
       initiator_(initiator),
-      identity_(NULL),
       ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10),
       ice_tiebreaker_(rtc::CreateRandomId64()),
       role_switch_(false),
@@ -390,13 +389,16 @@
   return initiator_ ? local_description_.get() : remote_description_.get();
 }
 
-bool BaseSession::SetIdentity(rtc::SSLIdentity* identity) {
-  if (identity_)
+bool BaseSession::SetCertificate(
+    const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
+  if (certificate_)
     return false;
-  identity_ = identity;
+  if (!certificate)
+    return false;
+  certificate_ = certificate;
   for (TransportMap::iterator iter = transports_.begin();
        iter != transports_.end(); ++iter) {
-    iter->second->SetIdentity(identity_);
+    iter->second->SetCertificate(certificate_);
   }
   return true;
 }
@@ -543,8 +545,8 @@
                                   new TransportWrapper(transport));
   transproxy->SignalCandidatesReady.connect(
       this, &BaseSession::OnTransportProxyCandidatesReady);
-  if (identity_)
-    transproxy->SetIdentity(identity_);
+  if (certificate_)
+    transproxy->SetCertificate(certificate_);
   transports_[content_name] = transproxy;
 
   return transproxy;
@@ -575,7 +577,7 @@
 Transport* BaseSession::CreateTransport(const std::string& content_name) {
   Transport* transport = new DtlsTransport<P2PTransport>(
       signaling_thread(), worker_thread(), content_name, port_allocator(),
-      identity_);
+      certificate_);
   transport->SetChannelReceivingTimeout(ice_receiving_timeout_);
   return transport;
 }
diff --git a/webrtc/p2p/base/session.h b/webrtc/p2p/base/session.h
index 79ccafd..8d7aa21 100644
--- a/webrtc/p2p/base/session.h
+++ b/webrtc/p2p/base/session.h
@@ -20,6 +20,7 @@
 #include "webrtc/p2p/base/port.h"
 #include "webrtc/p2p/base/transport.h"
 #include "webrtc/base/refcount.h"
+#include "webrtc/base/rtccertificate.h"
 #include "webrtc/base/scoped_ptr.h"
 #include "webrtc/base/scoped_ref_ptr.h"
 #include "webrtc/base/socketaddress.h"
@@ -100,7 +101,8 @@
 
   // Simple functions that thunk down to the same functions on Transport.
   void SetIceRole(IceRole role);
-  void SetIdentity(rtc::SSLIdentity* identity);
+  void SetCertificate(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
   bool SetLocalTransportDescription(const TransportDescription& description,
                                     ContentAction action,
                                     std::string* error_desc);
@@ -315,14 +317,19 @@
   virtual void DestroyChannel(const std::string& content_name,
                               int component);
 
-  rtc::SSLIdentity* identity() { return identity_; }
-
   // Set the ice connection receiving timeout.
   void SetIceConnectionReceivingTimeout(int timeout_ms);
 
+  // For testing.
+  const rtc::scoped_refptr<rtc::RTCCertificate>&
+  certificate_for_testing() const {
+    return certificate_;
+  }
+
  protected:
   // Specifies the identity to use in this session.
-  bool SetIdentity(rtc::SSLIdentity* identity);
+  bool SetCertificate(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
 
   bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version);
 
@@ -444,7 +451,7 @@
   const std::string sid_;
   const std::string content_type_;
   bool initiator_;
-  rtc::SSLIdentity* identity_;
+  rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
   rtc::SSLProtocolVersion ssl_max_version_;
   rtc::scoped_ptr<const SessionDescription> local_description_;
   rtc::scoped_ptr<SessionDescription> remote_description_;
diff --git a/webrtc/p2p/base/transport.cc b/webrtc/p2p/base/transport.cc
index 8b68a97..5f28c40 100644
--- a/webrtc/p2p/base/transport.cc
+++ b/webrtc/p2p/base/transport.cc
@@ -126,15 +126,18 @@
   worker_thread_->Invoke<void>(Bind(&Transport::SetIceRole_w, this, role));
 }
 
-void Transport::SetIdentity(rtc::SSLIdentity* identity) {
-  worker_thread_->Invoke<void>(Bind(&Transport::SetIdentity_w, this, identity));
+void Transport::SetCertificate(
+    const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
+  worker_thread_->Invoke<void>(Bind(&Transport::SetCertificate_w, this,
+                                    certificate));
 }
 
-bool Transport::GetIdentity(rtc::SSLIdentity** identity) {
+bool Transport::GetCertificate(
+    rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
   // The identity is set on the worker thread, so for safety it must also be
   // acquired on the worker thread.
   return worker_thread_->Invoke<bool>(
-      Bind(&Transport::GetIdentity_w, this, identity));
+      Bind(&Transport::GetCertificate_w, this, certificate));
 }
 
 bool Transport::GetRemoteCertificate(rtc::SSLCertificate** cert) {
diff --git a/webrtc/p2p/base/transport.h b/webrtc/p2p/base/transport.h
index 4093240..2e94c74 100644
--- a/webrtc/p2p/base/transport.h
+++ b/webrtc/p2p/base/transport.h
@@ -38,6 +38,7 @@
 #include "webrtc/p2p/base/transportinfo.h"
 #include "webrtc/base/criticalsection.h"
 #include "webrtc/base/messagequeue.h"
+#include "webrtc/base/rtccertificate.h"
 #include "webrtc/base/sigslot.h"
 #include "webrtc/base/sslstreamadapter.h"
 
@@ -145,9 +146,9 @@
   virtual ~Transport();
 
   // Returns the signaling thread. The app talks to Transport on this thread.
-  rtc::Thread* signaling_thread() { return signaling_thread_; }
+  rtc::Thread* signaling_thread() const { return signaling_thread_; }
   // Returns the worker thread. The actual networking is done on this thread.
-  rtc::Thread* worker_thread() { return worker_thread_; }
+  rtc::Thread* worker_thread() const { return worker_thread_; }
 
   // Returns the content_name of this transport.
   const std::string& content_name() const { return content_name_; }
@@ -200,10 +201,11 @@
   void SetChannelReceivingTimeout(int timeout_ms);
 
   // Must be called before applying local session description.
-  void SetIdentity(rtc::SSLIdentity* identity);
+  void SetCertificate(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
 
   // Get a copy of the local identity provided by SetIdentity.
-  bool GetIdentity(rtc::SSLIdentity** identity);
+  bool GetCertificate(rtc::scoped_refptr<rtc::RTCCertificate>* certificate);
 
   // Get a copy of the remote certificate in use by the specified channel.
   bool GetRemoteCertificate(rtc::SSLCertificate** cert);
@@ -299,9 +301,11 @@
     return remote_description_.get();
   }
 
-  virtual void SetIdentity_w(rtc::SSLIdentity* identity) {}
+  virtual void SetCertificate_w(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {}
 
-  virtual bool GetIdentity_w(rtc::SSLIdentity** identity) {
+  virtual bool GetCertificate_w(
+      rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
     return false;
   }