Revert "Create a in-memory DTLS identity store that keeps a free identity generated in the background."

Test failure: http://chromegw/i/client.webrtc/builders/Linux32%20Release/builds/3557

This reverts commit df512cc8b73ff519dcdf63a2603ab312d3443402.

TBR=andrew@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/41089004

Cr-Commit-Position: refs/heads/master@{#8579}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8579 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/app/webrtc/dtlsidentityservice.cc b/talk/app/webrtc/dtlsidentityservice.cc
index b4b7279..217056e 100644
--- a/talk/app/webrtc/dtlsidentityservice.cc
+++ b/talk/app/webrtc/dtlsidentityservice.cc
@@ -26,25 +26,3 @@
  */
 
 #include "talk/app/webrtc/dtlsidentityservice.h"
-
-#include "talk/app/webrtc/dtlsidentitystore.h"
-#include "webrtc/base/logging.h"
-
-namespace webrtc {
-
-bool DtlsIdentityService::RequestIdentity(
-    const std::string& identity_name,
-    const std::string& common_name,
-    webrtc::DTLSIdentityRequestObserver* observer) {
-  if (identity_name != DtlsIdentityStore::kIdentityName ||
-      common_name != DtlsIdentityStore::kIdentityName) {
-    LOG(LS_WARNING) << "DtlsIdentityService::RequestIdentity called with "
-                    << "unsupported params, identity_name=" << identity_name
-                    << ", common_name=" << common_name;
-    return false;
-  }
-  store_->RequestIdentity(observer);
-  return true;
-}
-
-}  // namespace webrtc
diff --git a/talk/app/webrtc/dtlsidentityservice.h b/talk/app/webrtc/dtlsidentityservice.h
index 760cab4..627403a 100644
--- a/talk/app/webrtc/dtlsidentityservice.h
+++ b/talk/app/webrtc/dtlsidentityservice.h
@@ -24,36 +24,3 @@
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
-#ifndef TALK_APP_WEBRTC_DTLSIDENTITYSERVICE_H_
-#define TALK_APP_WEBRTC_DTLSIDENTITYSERVICE_H_
-
-#include <string>
-
-#include "talk/app/webrtc/peerconnectioninterface.h"
-
-namespace webrtc {
-
-class DtlsIdentityStore;
-
-// This class forwards the request to DtlsIdentityStore to generate the
-// identity.
-class DtlsIdentityService : public webrtc::DTLSIdentityServiceInterface {
- public:
-  explicit DtlsIdentityService(DtlsIdentityStore* store) : store_(store) {}
-
-  // DTLSIdentityServiceInterface impl.
-  // |identity_name| and |common_name| must equal to
-  // DtlsIdentityStore::kIdentityName, otherwise the request will fail and false
-  // will be returned.
-  bool RequestIdentity(const std::string& identity_name,
-                       const std::string& common_name,
-                       webrtc::DTLSIdentityRequestObserver* observer) override;
-
- private:
-  DtlsIdentityStore* store_;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_DTLSIDENTITYSERVICE_H_
diff --git a/talk/app/webrtc/dtlsidentitystore.cc b/talk/app/webrtc/dtlsidentitystore.cc
index 67a4213..77a63a1 100644
--- a/talk/app/webrtc/dtlsidentitystore.cc
+++ b/talk/app/webrtc/dtlsidentitystore.cc
@@ -26,136 +26,3 @@
  */
 
 #include "talk/app/webrtc/dtlsidentitystore.h"
-
-#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
-#include "webrtc/base/logging.h"
-
-using webrtc::DTLSIdentityRequestObserver;
-using webrtc::WebRtcSessionDescriptionFactory;
-
-namespace webrtc {
-
-namespace {
-
-enum {
-  MSG_GENERATE_IDENTITY,
-  MSG_GENERATE_IDENTITY_RESULT,
-  MSG_RETURN_FREE_IDENTITY
-};
-
-typedef rtc::ScopedMessageData<rtc::SSLIdentity> IdentityResultMessageData;
-}  // namespace
-
-// Arbitrary constant used as common name for the identity.
-// Chosen to make the certificates more readable.
-const char DtlsIdentityStore::kIdentityName[] = "WebRTC";
-
-DtlsIdentityStore::DtlsIdentityStore(rtc::Thread* signaling_thread,
-                                     rtc::Thread* worker_thread)
-    : signaling_thread_(signaling_thread),
-      worker_thread_(worker_thread),
-      pending_jobs_(0) {}
-
-DtlsIdentityStore::~DtlsIdentityStore() {}
-
-void DtlsIdentityStore::Initialize() {
-  GenerateIdentity();
-}
-
-void DtlsIdentityStore::RequestIdentity(DTLSIdentityRequestObserver* observer) {
-  CHECK(rtc::Thread::Current() == signaling_thread_);
-  CHECK(observer);
-
-  // Must return the free identity async.
-  if (free_identity_.get()) {
-    IdentityResultMessageData* msg =
-        new IdentityResultMessageData(free_identity_.release());
-    signaling_thread_->Post(this, MSG_RETURN_FREE_IDENTITY, msg);
-  }
-
-  pending_oberservers_.push(observer);
-  GenerateIdentity();
-}
-
-void DtlsIdentityStore::OnMessage(rtc::Message* msg) {
-  switch (msg->message_id) {
-    case MSG_GENERATE_IDENTITY:
-      GenerateIdentity_w();
-      break;
-    case MSG_GENERATE_IDENTITY_RESULT: {
-      rtc::scoped_ptr<IdentityResultMessageData> pdata(
-          static_cast<IdentityResultMessageData*>(msg->pdata));
-      OnIdentityGenerated(pdata->data().Pass());
-      break;
-    }
-    case MSG_RETURN_FREE_IDENTITY: {
-      rtc::scoped_ptr<IdentityResultMessageData> pdata(
-          static_cast<IdentityResultMessageData*>(msg->pdata));
-      ReturnIdentity(pdata->data().Pass());
-      break;
-    }
-  }
-}
-
-bool DtlsIdentityStore::HasFreeIdentityForTesting() const {
-  return free_identity_.get();
-}
-
-void DtlsIdentityStore::GenerateIdentity() {
-  pending_jobs_++;
-  LOG(LS_VERBOSE) << "New DTLS identity generation is posted, "
-                  << "pending_identities=" << pending_jobs_;
-  worker_thread_->Post(this, MSG_GENERATE_IDENTITY, NULL);
-}
-
-void DtlsIdentityStore::OnIdentityGenerated(
-    rtc::scoped_ptr<rtc::SSLIdentity> identity) {
-  CHECK(rtc::Thread::Current() == signaling_thread_);
-
-  pending_jobs_--;
-  LOG(LS_VERBOSE) << "A DTLS identity generation job returned, "
-                  << "pending_identities=" << pending_jobs_;
-
-  if (pending_oberservers_.empty()) {
-    if (!free_identity_.get()) {
-      free_identity_.reset(identity.release());
-      LOG(LS_VERBOSE) << "A free DTLS identity is saved";
-    }
-    return;
-  }
-  ReturnIdentity(identity.Pass());
-}
-
-void DtlsIdentityStore::ReturnIdentity(
-    rtc::scoped_ptr<rtc::SSLIdentity> identity) {
-  CHECK(!free_identity_.get());
-  CHECK(!pending_oberservers_.empty());
-
-  rtc::scoped_refptr<DTLSIdentityRequestObserver> observer =
-      pending_oberservers_.front();
-  pending_oberservers_.pop();
-
-  if (identity.get()) {
-    observer->OnSuccessWithIdentityObj(identity.Pass());
-  } else {
-    // Pass an arbitrary error code.
-    observer->OnFailure(0);
-    LOG(LS_WARNING) << "Failed to generate SSL identity";
-  }
-
-  if (pending_oberservers_.empty() && pending_jobs_ == 0) {
-    // Generate a free identity in the background.
-    GenerateIdentity();
-  }
-}
-
-void DtlsIdentityStore::GenerateIdentity_w() {
-  CHECK(rtc::Thread::Current() == worker_thread_);
-
-  rtc::SSLIdentity* identity = rtc::SSLIdentity::Generate(kIdentityName);
-
-  IdentityResultMessageData* msg = new IdentityResultMessageData(identity);
-  signaling_thread_->Post(this, MSG_GENERATE_IDENTITY_RESULT, msg);
-}
-
-}  // namespace webrtc
diff --git a/talk/app/webrtc/dtlsidentitystore.h b/talk/app/webrtc/dtlsidentitystore.h
index 5bd9cd3..627403a 100644
--- a/talk/app/webrtc/dtlsidentitystore.h
+++ b/talk/app/webrtc/dtlsidentitystore.h
@@ -24,66 +24,3 @@
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
-#ifndef TALK_APP_WEBRTC_DTLSIDENTITYSTORE_H_
-#define TALK_APP_WEBRTC_DTLSIDENTITYSTORE_H_
-
-#include <queue>
-#include <string>
-
-#include "talk/app/webrtc/peerconnectioninterface.h"
-#include "webrtc/base/messagehandler.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/base/scoped_ref_ptr.h"
-
-namespace webrtc {
-class DTLSIdentityRequestObserver;
-class SSLIdentity;
-class Thread;
-
-// This class implements an in-memory DTLS identity store, which generates the
-// DTLS identity on the worker thread.
-// APIs calls must be made on the signaling thread and the callbacks are also
-// called on the signaling thread.
-class DtlsIdentityStore : public rtc::MessageHandler {
- public:
-  static const char kIdentityName[];
-
-  DtlsIdentityStore(rtc::Thread* signaling_thread,
-                    rtc::Thread* worker_thread);
-  ~DtlsIdentityStore();
-
-  // Initialize will start generating the free identity in the background.
-  void Initialize();
-
-  // The |observer| will be called when the requested identity is ready, or when
-  // identity generation fails.
-  void RequestIdentity(webrtc::DTLSIdentityRequestObserver* observer);
-
-  // rtc::MessageHandler override;
-  void OnMessage(rtc::Message* msg) override;
-
-  // Returns true if there is a free identity, used for unit tests.
-  bool HasFreeIdentityForTesting() const;
-
- private:
-  void GenerateIdentity();
-  void OnIdentityGenerated(rtc::scoped_ptr<rtc::SSLIdentity> identity);
-  void ReturnIdentity(rtc::scoped_ptr<rtc::SSLIdentity> identity);
-
-  void GenerateIdentity_w();
-
-  rtc::Thread* signaling_thread_;
-  rtc::Thread* worker_thread_;
-
-  // These members should be accessed on the signaling thread only.
-  int pending_jobs_;
-  rtc::scoped_ptr<rtc::SSLIdentity> free_identity_;
-  typedef std::queue<rtc::scoped_refptr<webrtc::DTLSIdentityRequestObserver>>
-      OberserverList;
-  OberserverList pending_oberservers_;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_DTLSIDENTITYSTORE_H_
diff --git a/talk/app/webrtc/dtlsidentitystore_unittest.cc b/talk/app/webrtc/dtlsidentitystore_unittest.cc
index 5896952..627403a 100644
--- a/talk/app/webrtc/dtlsidentitystore_unittest.cc
+++ b/talk/app/webrtc/dtlsidentitystore_unittest.cc
@@ -24,86 +24,3 @@
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
-#include "talk/app/webrtc/dtlsidentitystore.h"
-
-#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
-#include "webrtc/base/gunit.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/base/ssladapter.h"
-
-using webrtc::DtlsIdentityStore;
-using webrtc::WebRtcSessionDescriptionFactory;
-
-static const int kTimeoutMs = 5000;
-
-class MockDtlsIdentityRequestObserver :
-    public webrtc::DTLSIdentityRequestObserver {
- public:
-  MockDtlsIdentityRequestObserver()
-      : call_back_called_(false), last_request_success_(false) {}
-  void OnFailure(int error) override {
-    EXPECT_FALSE(call_back_called_);
-    call_back_called_ = true;
-    last_request_success_ = false;
-  }
-  void OnSuccess(const std::string& der_cert,
-                 const std::string& der_private_key) {
-    LOG(LS_WARNING) << "The string version of OnSuccess is called unexpectedly";
-    EXPECT_TRUE(false);
-  }
-  void OnSuccessWithIdentityObj(
-      rtc::scoped_ptr<rtc::SSLIdentity> identity) override {
-    EXPECT_FALSE(call_back_called_);
-    call_back_called_ = true;
-    last_request_success_ = true;
-  }
-
-  void Reset() {
-    call_back_called_ = false;
-    last_request_success_ = false;
-  }
-
-  bool LastRequestSucceeded() const {
-    return call_back_called_ && last_request_success_;
-  }
-
-  bool call_back_called() const {
-    return call_back_called_;
-  }
-
- private:
-  bool call_back_called_;
-  bool last_request_success_;
-};
-
-class DtlsIdentityStoreTest : public testing::Test {
- protected:
-  DtlsIdentityStoreTest()
-      : store_(new DtlsIdentityStore(rtc::Thread::Current(),
-                                     rtc::Thread::Current())),
-        observer_(
-            new rtc::RefCountedObject<MockDtlsIdentityRequestObserver>()) {
-    store_->Initialize();
-  }
-  ~DtlsIdentityStoreTest() {}
-
-  static void SetUpTestCase() {
-    rtc::InitializeSSL();
-  }
-  static void TearDownTestCase() {
-    rtc::CleanupSSL();
-  }
-
-  rtc::scoped_ptr<DtlsIdentityStore> store_;
-  rtc::scoped_refptr<MockDtlsIdentityRequestObserver> observer_;
-};
-
-TEST_F(DtlsIdentityStoreTest, RequestIdentitySuccess) {
-  EXPECT_TRUE_WAIT(store_->HasFreeIdentityForTesting(), kTimeoutMs);
-
-  store_->RequestIdentity(observer_.get());
-  EXPECT_TRUE_WAIT(observer_->LastRequestSucceeded(), kTimeoutMs);
-
-  EXPECT_TRUE_WAIT(store_->HasFreeIdentityForTesting(), kTimeoutMs);
-}
diff --git a/talk/app/webrtc/peerconnectionfactory.cc b/talk/app/webrtc/peerconnectionfactory.cc
index 9f1e858..852f4d9 100644
--- a/talk/app/webrtc/peerconnectionfactory.cc
+++ b/talk/app/webrtc/peerconnectionfactory.cc
@@ -28,8 +28,6 @@
 #include "talk/app/webrtc/peerconnectionfactory.h"
 
 #include "talk/app/webrtc/audiotrack.h"
-#include "talk/app/webrtc/dtlsidentityservice.h"
-#include "talk/app/webrtc/dtlsidentitystore.h"
 #include "talk/app/webrtc/localaudiosource.h"
 #include "talk/app/webrtc/mediastreamproxy.h"
 #include "talk/app/webrtc/mediastreamtrackproxy.h"
@@ -163,11 +161,6 @@
   if (!channel_manager_->Init()) {
     return false;
   }
-
-  dtls_identity_store_.reset(
-      new DtlsIdentityStore(signaling_thread_, worker_thread_));
-  dtls_identity_store_->Initialize();
-
   return true;
 }
 
@@ -205,10 +198,6 @@
   DCHECK(signaling_thread_->IsCurrent());
   DCHECK(allocator_factory || default_allocator_factory_);
 
-  if (!dtls_identity_service) {
-    dtls_identity_service = new DtlsIdentityService(dtls_identity_store_.get());
-  }
-
   PortAllocatorFactoryInterface* chosen_allocator_factory =
       allocator_factory ? allocator_factory : default_allocator_factory_.get();
   chosen_allocator_factory->SetNetworkIgnoreMask(options_.network_ignore_mask);
diff --git a/talk/app/webrtc/peerconnectionfactory.h b/talk/app/webrtc/peerconnectionfactory.h
index d6bf03f..f0d0139 100644
--- a/talk/app/webrtc/peerconnectionfactory.h
+++ b/talk/app/webrtc/peerconnectionfactory.h
@@ -38,8 +38,6 @@
 
 namespace webrtc {
 
-class DtlsIdentityStore;
-
 class PeerConnectionFactory : public PeerConnectionFactoryInterface {
  public:
   virtual void SetOptions(const Options& options) {
@@ -111,8 +109,6 @@
   // injected any. In that case, video engine will use the internal SW decoder.
   rtc::scoped_ptr<cricket::WebRtcVideoDecoderFactory>
       video_decoder_factory_;
-
-  rtc::scoped_ptr<webrtc::DtlsIdentityStore> dtls_identity_store_;
 };
 
 }  // namespace webrtc
diff --git a/talk/app/webrtc/peerconnectioninterface.h b/talk/app/webrtc/peerconnectioninterface.h
index 6f6eb24..391255f 100644
--- a/talk/app/webrtc/peerconnectioninterface.h
+++ b/talk/app/webrtc/peerconnectioninterface.h
@@ -82,7 +82,6 @@
 #include "webrtc/base/socketaddress.h"
 
 namespace rtc {
-class SSLIdentity;
 class Thread;
 }
 
@@ -438,14 +437,8 @@
 class DTLSIdentityRequestObserver : public rtc::RefCountInterface {
  public:
   virtual void OnFailure(int error) = 0;
-  // TODO(jiayl): Unify the OnSuccess method once Chrome code is updated.
   virtual void OnSuccess(const std::string& der_cert,
                          const std::string& der_private_key) = 0;
-  // |identity| is a scoped_ptr because rtc::SSLIdentity is not copyable and the
-  // client has to get the ownership of the object to make use of it.
-  virtual void OnSuccessWithIdentityObj(
-      rtc::scoped_ptr<rtc::SSLIdentity> identity) = 0;
-
  protected:
   virtual ~DTLSIdentityRequestObserver() {}
 };
@@ -510,7 +503,6 @@
 
   virtual void SetOptions(const Options& options) = 0;
 
-  // This method takes the ownership of |dtls_identity_service|.
   virtual rtc::scoped_refptr<PeerConnectionInterface>
       CreatePeerConnection(
           const PeerConnectionInterface::RTCConfiguration& configuration,
diff --git a/talk/app/webrtc/peerconnectioninterface_unittest.cc b/talk/app/webrtc/peerconnectioninterface_unittest.cc
index aa526c3..3b5c354 100644
--- a/talk/app/webrtc/peerconnectioninterface_unittest.cc
+++ b/talk/app/webrtc/peerconnectioninterface_unittest.cc
@@ -256,14 +256,6 @@
     // DTLS does not work in a loopback call, so is disabled for most of the
     // tests in this file. We only create a FakeIdentityService if the test
     // explicitly sets the constraint.
-    FakeConstraints default_constraints;
-    if (!constraints) {
-      constraints = &default_constraints;
-
-      default_constraints.AddMandatory(
-          webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
-    }
-
     FakeIdentityService* dtls_service = NULL;
     bool dtls;
     if (FindConstraint(constraints,
diff --git a/talk/app/webrtc/test/fakeconstraints.h b/talk/app/webrtc/test/fakeconstraints.h
index 8673d85..ff4a208 100644
--- a/talk/app/webrtc/test/fakeconstraints.h
+++ b/talk/app/webrtc/test/fakeconstraints.h
@@ -112,7 +112,6 @@
 
   void SetAllowRtpDataChannels() {
     SetMandatory(MediaConstraintsInterface::kEnableRtpDataChannels, true);
-    SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, false);
   }
 
   void SetOptionalVAD(bool enable) {
diff --git a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
index aab24cf..dbec959 100644
--- a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
+++ b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
@@ -27,7 +27,6 @@
 
 #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
 
-#include "talk/app/webrtc/dtlsidentitystore.h"
 #include "talk/app/webrtc/jsep.h"
 #include "talk/app/webrtc/jsepsessiondescription.h"
 #include "talk/app/webrtc/mediaconstraintsinterface.h"
@@ -41,6 +40,10 @@
 static const char kFailedDueToIdentityFailed[] =
     " failed because DTLS identity request failed";
 
+// Arbitrary constant used as common name for the identity.
+// Chosen to make the certificates more readable.
+static const char kWebRTCIdentityName[] = "WebRTC";
+
 static const uint64 kInitSessionVersion = 2;
 
 static bool CompareStream(const MediaSessionOptions::Stream& stream1,
@@ -81,30 +84,6 @@
 };
 }  // namespace
 
-void WebRtcIdentityRequestObserver::OnFailure(int error) {
-  SignalRequestFailed(error);
-}
-
-void WebRtcIdentityRequestObserver::OnSuccess(
-    const std::string& der_cert, const std::string& der_private_key) {
-  std::string pem_cert = rtc::SSLIdentity::DerToPem(
-      rtc::kPemTypeCertificate,
-      reinterpret_cast<const unsigned char*>(der_cert.data()),
-      der_cert.length());
-  std::string pem_key = rtc::SSLIdentity::DerToPem(
-      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);
-}
-
-void WebRtcIdentityRequestObserver::OnSuccessWithIdentityObj(
-    rtc::scoped_ptr<rtc::SSLIdentity> identity) {
-  SignalIdentityReady(identity.release());
-}
-
 // static
 void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription(
     const SessionDescriptionInterface* source_desc,
@@ -162,12 +141,11 @@
     identity_request_observer_->SignalRequestFailed.connect(
         this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed);
     identity_request_observer_->SignalIdentityReady.connect(
-        this, &WebRtcSessionDescriptionFactory::SetIdentity);
+        this, &WebRtcSessionDescriptionFactory::OnIdentityReady);
 
-    if (identity_service_->RequestIdentity(
-            DtlsIdentityStore::kIdentityName,
-            DtlsIdentityStore::kIdentityName,
-            identity_request_observer_)) {
+    if (identity_service_->RequestIdentity(kWebRTCIdentityName,
+                                           kWebRTCIdentityName,
+                                           identity_request_observer_)) {
       LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sent DTLS identity request.";
       identity_request_state_ = IDENTITY_WAITING;
     } else {
@@ -312,7 +290,7 @@
     }
     case MSG_GENERATE_IDENTITY: {
       LOG(LS_INFO) << "Generating identity.";
-      SetIdentity(rtc::SSLIdentity::Generate(DtlsIdentityStore::kIdentityName));
+      SetIdentity(rtc::SSLIdentity::Generate(kWebRTCIdentityName));
       break;
     }
     default:
@@ -434,10 +412,28 @@
   }
 }
 
+void WebRtcSessionDescriptionFactory::OnIdentityReady(
+    const std::string& der_cert,
+    const std::string& der_private_key) {
+  ASSERT(signaling_thread_->IsCurrent());
+  LOG(LS_VERBOSE) << "Identity is successfully generated.";
+
+  std::string pem_cert = rtc::SSLIdentity::DerToPem(
+      rtc::kPemTypeCertificate,
+      reinterpret_cast<const unsigned char*>(der_cert.data()),
+      der_cert.length());
+  std::string pem_key = rtc::SSLIdentity::DerToPem(
+      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);
+  SetIdentity(identity);
+}
+
 void WebRtcSessionDescriptionFactory::SetIdentity(
     rtc::SSLIdentity* identity) {
-  LOG(LS_VERBOSE) << "Setting new identity";
-
   identity_request_state_ = IDENTITY_SUCCEEDED;
   SignalIdentityReady(identity);
 
diff --git a/talk/app/webrtc/webrtcsessiondescriptionfactory.h b/talk/app/webrtc/webrtcsessiondescriptionfactory.h
index 41798a4..6e01dc7 100644
--- a/talk/app/webrtc/webrtcsessiondescriptionfactory.h
+++ b/talk/app/webrtc/webrtcsessiondescriptionfactory.h
@@ -50,14 +50,16 @@
                                       public sigslot::has_slots<> {
  public:
   // DTLSIdentityRequestObserver overrides.
-  void OnFailure(int error) override;
-  void OnSuccess(const std::string& der_cert,
-                 const std::string& der_private_key) override;
-  void OnSuccessWithIdentityObj(
-      rtc::scoped_ptr<rtc::SSLIdentity> identity) override;
+  virtual void OnFailure(int error) {
+    SignalRequestFailed(error);
+  }
+  virtual void OnSuccess(const std::string& der_cert,
+                         const std::string& der_private_key) {
+    SignalIdentityReady(der_cert, der_private_key);
+  }
 
   sigslot::signal1<int> SignalRequestFailed;
-  sigslot::signal1<rtc::SSLIdentity*> SignalIdentityReady;
+  sigslot::signal2<const std::string&, const std::string&> SignalIdentityReady;
 };
 
 struct CreateSessionDescriptionRequest {
@@ -141,6 +143,8 @@
       SessionDescriptionInterface* description);
 
   void OnIdentityRequestFailed(int error);
+  void OnIdentityReady(const std::string& der_cert,
+                       const std::string& der_private_key);
   void SetIdentity(rtc::SSLIdentity* identity);
 
   std::queue<CreateSessionDescriptionRequest>