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
This commit is contained in:
jiayl@webrtc.org 2015-03-03 20:34:38 +00:00
parent bcef431902
commit 8ad96605c1
12 changed files with 39 additions and 405 deletions

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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);
}

View File

@ -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 @@ bool PeerConnectionFactory::Initialize() {
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 @@ PeerConnectionFactory::CreatePeerConnection(
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);

View File

@ -38,8 +38,6 @@
namespace webrtc {
class DtlsIdentityStore;
class PeerConnectionFactory : public PeerConnectionFactoryInterface {
public:
virtual void SetOptions(const Options& options) {
@ -111,8 +109,6 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface {
// 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

View File

@ -82,7 +82,6 @@
#include "webrtc/base/socketaddress.h"
namespace rtc {
class SSLIdentity;
class Thread;
}
@ -438,14 +437,8 @@ class PortAllocatorFactoryInterface : public rtc::RefCountInterface {
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 @@ class PeerConnectionFactoryInterface : public rtc::RefCountInterface {
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,

View File

@ -256,14 +256,6 @@ class PeerConnectionInterfaceTest : public testing::Test {
// 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,

View File

@ -112,7 +112,6 @@ class FakeConstraints : public webrtc::MediaConstraintsInterface {
void SetAllowRtpDataChannels() {
SetMandatory(MediaConstraintsInterface::kEnableRtpDataChannels, true);
SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, false);
}
void SetOptionalVAD(bool enable) {

View File

@ -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 @@ namespace {
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 @@ struct CreateSessionDescriptionMsg : public rtc::MessageData {
};
} // 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 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory(
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 @@ void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) {
}
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::OnIdentityRequestFailed(int error) {
}
}
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);

View File

@ -50,14 +50,16 @@ class WebRtcIdentityRequestObserver : public DTLSIdentityRequestObserver,
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 @@ class WebRtcSessionDescriptionFactory : public rtc::MessageHandler,
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>