diff --git a/talk/app/webrtc/statscollector.cc b/talk/app/webrtc/statscollector.cc index ad64639eb9..eb32356400 100644 --- a/talk/app/webrtc/statscollector.cc +++ b/talk/app/webrtc/statscollector.cc @@ -692,7 +692,7 @@ void StatsCollector::ExtractSessionInfo() { // 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 @@ void StatsCollector::ExtractSessionInfo() { cricket::Transport* transport = session_->GetTransport(transport_iter.second.content_name); - rtc::scoped_ptr identity; - if (transport && transport->GetIdentity(identity.accept())) { - StatsReport* r = AddCertificateReports(&(identity->certificate())); + rtc::scoped_refptr 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 ab9181f487..fd1ad617af 100644 --- a/talk/app/webrtc/statscollector_unittest.cc +++ b/talk/app/webrtc/statscollector_unittest.cc @@ -656,7 +656,9 @@ class StatsCollectorTest : public testing::Test { transport_stats; // Fake certificates to report. - rtc::FakeSSLIdentity local_identity(local_cert); + rtc::scoped_refptr local_certificate( + rtc::RTCCertificate::Create(rtc::scoped_ptr( + new rtc::FakeSSLIdentity(local_cert)).Pass())); rtc::scoped_ptr remote_cert_copy( remote_cert.GetReference()); @@ -666,7 +668,7 @@ class StatsCollectorTest : public testing::Test { session_.signaling_thread(), session_.worker_thread(), transport_stats.content_name)); - transport->SetIdentity(&local_identity); + transport->SetCertificate(local_certificate); cricket::FakeTransportChannel* channel = static_cast( transport->CreateChannel(channel_stats.component)); diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc index 3d192c22d1..f73cf39806 100644 --- a/talk/app/webrtc/webrtcsession.cc +++ b/talk/app/webrtc/webrtcsession.cc @@ -564,7 +564,6 @@ WebRtcSession::~WebRtcSession() { for (size_t i = 0; i < saved_candidates_.size(); ++i) { delete saved_candidates_[i]; } - delete identity(); } bool WebRtcSession::Initialize( @@ -751,8 +750,8 @@ bool WebRtcSession::Initialize( } } - 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 @@ void WebRtcSession::ResetIceRestartLatch() { ice_restart_latch_->Reset(); } -void WebRtcSession::OnIdentityReady(rtc::SSLIdentity* identity) { - SetIdentity(identity); +void WebRtcSession::OnCertificateReady( + const rtc::scoped_refptr& 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 b580d3439b..bb405c5da4 100644 --- a/talk/app/webrtc/webrtcsession.h +++ b/talk/app/webrtc/webrtcsession.h @@ -246,13 +246,14 @@ class WebRtcSession : public cricket::BaseSession, 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& 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 a23130db50..2c52d1301e 100644 --- a/talk/app/webrtc/webrtcsession_unittest.cc +++ b/talk/app/webrtc/webrtcsession_unittest.cc @@ -3575,20 +3575,17 @@ TEST_P(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) { 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 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 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 @@ TEST_P(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) { 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 offer(CreateOffer()); @@ -3634,7 +3631,7 @@ TEST_P(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) { 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 offer(CreateOffer()); EXPECT_TRUE(offer != NULL); @@ -3646,7 +3643,7 @@ TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) { 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 offer(CreateOffer()); EXPECT_TRUE(offer == NULL); diff --git a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc index 4336372b57..41bcfa0593 100644 --- a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc +++ b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc @@ -98,14 +98,14 @@ void WebRtcIdentityRequestObserver::OnSuccess( rtc::kPemTypeRsaPrivateKey, reinterpret_cast(der_private_key.data()), der_private_key.length()); - rtc::SSLIdentity* identity = - rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert); - SignalIdentityReady(identity); + rtc::scoped_ptr identity( + rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert)); + SignalCertificateReady(rtc::RTCCertificate::Create(identity.Pass())); } void WebRtcIdentityRequestObserver::OnSuccess( rtc::scoped_ptr identity) { - SignalIdentityReady(identity.release()); + SignalCertificateReady(rtc::RTCCertificate::Create(identity.Pass())); } // static @@ -195,8 +195,8 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( 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 @@ void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { static_cast*>( msg->pdata); LOG(LS_INFO) << "Using certificate supplied to the constructor."; - // TODO(hbos): Pass around scoped_refptr 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 @@ void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) { FailPendingRequests(kFailedDueToIdentityFailed); } -void WebRtcSessionDescriptionFactory::SetIdentity( - rtc::SSLIdentity* identity) { - LOG(LS_VERBOSE) << "Setting new identity"; +void WebRtcSessionDescriptionFactory::SetCertificate( + const rtc::scoped_refptr& 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 8ba0ac2f4f..8abf6aaa26 100644 --- a/talk/app/webrtc/webrtcsessiondescriptionfactory.h +++ b/talk/app/webrtc/webrtcsessiondescriptionfactory.h @@ -58,7 +58,8 @@ class WebRtcIdentityRequestObserver : public DtlsIdentityRequestObserver, void OnSuccess(rtc::scoped_ptr identity) override; sigslot::signal1 SignalRequestFailed; - sigslot::signal1 SignalIdentityReady; + sigslot::signal1&> + SignalCertificateReady; }; struct CreateSessionDescriptionRequest { @@ -134,7 +135,8 @@ class WebRtcSessionDescriptionFactory : public rtc::MessageHandler, void SetSdesPolicy(cricket::SecurePolicy secure_policy); cricket::SecurePolicy SdesPolicy() const; - sigslot::signal1 SignalIdentityReady; + sigslot::signal1&> + SignalCertificateReady; // For testing. bool waiting_for_certificate_for_testing() const { @@ -176,7 +178,8 @@ class WebRtcSessionDescriptionFactory : public rtc::MessageHandler, SessionDescriptionInterface* description); void OnIdentityRequestFailed(int error); - void SetIdentity(rtc::SSLIdentity* identity); + void SetCertificate( + const rtc::scoped_refptr& certificate); std::queue create_session_description_requests_; diff --git a/talk/session/media/channel_unittest.cc b/talk/session/media/channel_unittest.cc index a79302865e..03f33a4d13 100644 --- a/talk/session/media/channel_unittest.cc +++ b/talk/session/media/channel_unittest.cc @@ -196,13 +196,15 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { 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::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::Generate( + "session2", rtc::KT_DEFAULT)).Pass())); } // Add stream information (SSRC) to the local content but not to the remote @@ -1791,8 +1793,6 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { typename T::Content local_media_content2_; typename T::Content remote_media_content1_; typename T::Content remote_media_content2_; - rtc::scoped_ptr identity1_; - rtc::scoped_ptr 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 27cece49d0..0c53ff9c5b 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 @@ namespace cricket { class PortAllocator; // Base should be a descendant of cricket::Transport +// TODO(hbos): Add appropriate DCHECK thread checks to all methods. template class DtlsTransport : public Base { public: @@ -30,9 +32,9 @@ class DtlsTransport : public Base { rtc::Thread* worker_thread, const std::string& content_name, PortAllocator* allocator, - rtc::SSLIdentity* identity) + const rtc::scoped_refptr& 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 @@ class DtlsTransport : public Base { ~DtlsTransport() { Base::DestroyAllChannels(); } - virtual void SetIdentity_w(rtc::SSLIdentity* identity) { - identity_ = identity; + void SetCertificate_w( + const rtc::scoped_refptr& certificate) override { + DCHECK(Base::worker_thread()->IsCurrent()); + certificate_ = certificate; } - virtual bool GetIdentity_w(rtc::SSLIdentity** identity) { - if (!identity_) + bool GetCertificate_w( + rtc::scoped_refptr* 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 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 @@ class DtlsTransport : public Base { 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 @@ class DtlsTransport : public Base { 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 @@ class DtlsTransport : public Base { } 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 @@ class DtlsTransport : public Base { 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 @@ class DtlsTransport : public Base { return Base::ApplyNegotiatedTransportDescription_w(channel, error_desc); } - rtc::SSLIdentity* identity_; + rtc::scoped_refptr certificate_; rtc::SSLRole secure_role_; rtc::SSLProtocolVersion ssl_max_version_; rtc::scoped_ptr remote_fingerprint_; diff --git a/webrtc/p2p/base/dtlstransportchannel_unittest.cc b/webrtc/p2p/base/dtlstransportchannel_unittest.cc index 26f6578d7b..34aa651af7 100644 --- a/webrtc/p2p/base/dtlstransportchannel_unittest.cc +++ b/webrtc/p2p/base/dtlstransportchannel_unittest.cc @@ -58,12 +58,16 @@ class DtlsTestClient : public sigslot::has_slots<> { 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::Generate(name_, key_type)).Pass()); + } + const rtc::scoped_refptr& certificate() { + return certificate_; } - rtc::SSLIdentity* identity() { return identity_.get(); } void SetupSrtp() { - ASSERT(identity_.get() != NULL); + ASSERT(certificate_); use_dtls_srtp_ = true; } void SetupMaxProtocolVersion(rtc::SSLProtocolVersion version) { @@ -72,8 +76,8 @@ class DtlsTestClient : public sigslot::has_slots<> { } void SetupChannels(int count, cricket::IceRole role) { transport_.reset(new cricket::DtlsTransport( - 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 @@ class DtlsTestClient : public sigslot::has_slots<> { 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& local_cert, + const rtc::scoped_refptr& remote_cert, cricket::ContentAction action, ConnectionRole local_role, ConnectionRole remote_role, int flags) { rtc::scoped_ptr local_fingerprint; rtc::scoped_ptr 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 @@ class DtlsTestClient : public sigslot::has_slots<> { 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 @@ class DtlsTestClient : public sigslot::has_slots<> { 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 @@ class DtlsTestClient : public sigslot::has_slots<> { static_cast(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 @@ class DtlsTestClient : public sigslot::has_slots<> { 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 @@ class DtlsTestClient : public sigslot::has_slots<> { std::string name_; rtc::Thread* signaling_thread_; rtc::Thread* worker_thread_; - rtc::scoped_ptr identity_; + rtc::scoped_refptr certificate_; rtc::scoped_ptr transport_; std::vector channels_; size_t packet_size_; @@ -407,10 +411,10 @@ class DtlsTransportChannelTest : public testing::Test { } 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 @@ TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { PrepareDtls(true, true, rtc::KT_DEFAULT); Negotiate(); - rtc::scoped_ptr identity1; - rtc::scoped_ptr identity2; + rtc::scoped_refptr certificate1; + rtc::scoped_refptr certificate2; rtc::scoped_ptr remote_cert1; rtc::scoped_ptr 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 @@ TEST_F(DtlsTransportChannelTest, TestCertificatesAfterConnect) { PrepareDtls(true, true, rtc::KT_DEFAULT); ASSERT_TRUE(Connect()); - rtc::scoped_ptr identity1; - rtc::scoped_ptr identity2; + rtc::scoped_refptr certificate1; + rtc::scoped_refptr certificate2; rtc::scoped_ptr remote_cert1; rtc::scoped_ptr 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 b63958e4d3..5597a44dfa 100644 --- a/webrtc/p2p/base/fakesession.h +++ b/webrtc/p2p/base/fakesession.h @@ -38,6 +38,7 @@ struct PacketMessageData : public rtc::MessageData { // 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 @@ class FakeTransport : public Transport { 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 @@ class FakeTransport : public Transport { 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 @@ class FakeTransport : public Transport { } } - void set_identity(rtc::SSLIdentity* identity) { - identity_ = identity; + void set_certificate( + const rtc::scoped_refptr& certificate) { + certificate_ = certificate; } using Transport::local_description; @@ -385,14 +388,16 @@ class FakeTransport : public Transport { channels_.erase(channel->component()); delete channel; } - virtual void SetIdentity_w(rtc::SSLIdentity* identity) { - identity_ = identity; + void SetCertificate_w( + const rtc::scoped_refptr& certificate) override { + certificate_ = certificate; } - virtual bool GetIdentity_w(rtc::SSLIdentity** identity) { - if (!identity_) + bool GetCertificate_w( + rtc::scoped_refptr* certificate) override { + if (!certificate_) return false; - *identity = identity_->GetReference(); + *certificate = certificate_; return true; } @@ -407,7 +412,9 @@ class FakeTransport : public Transport { 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 @@ class FakeTransport : public Transport { ChannelMap channels_; FakeTransport* dest_; bool async_; - rtc::SSLIdentity* identity_; + rtc::scoped_refptr certificate_; }; // Fake session class, which can be passed into a BaseChannel object for @@ -474,13 +481,14 @@ class FakeSession : public BaseSession { } // 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& certificate) { for (TransportMap::const_iterator it = transport_proxies().begin(); it != transport_proxies().end(); ++it) { // We know that we have a FakeTransport* - static_cast(it->second->impl())->set_identity - (identity); + static_cast(it->second->impl())->set_certificate + (certificate); } } diff --git a/webrtc/p2p/base/session.cc b/webrtc/p2p/base/session.cc index 6c185113f9..23680b9be8 100644 --- a/webrtc/p2p/base/session.cc +++ b/webrtc/p2p/base/session.cc @@ -277,9 +277,9 @@ bool TransportProxy::OnRemoteCandidates(const Candidates& candidates, return true; } -void TransportProxy::SetIdentity( - rtc::SSLIdentity* identity) { - transport_->get()->SetIdentity(identity); +void TransportProxy::SetCertificate( + const rtc::scoped_refptr& certificate) { + transport_->get()->SetCertificate(certificate); } std::string BaseSession::StateToString(State state) { @@ -336,7 +336,6 @@ BaseSession::BaseSession(rtc::Thread* signaling_thread, 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 @@ const SessionDescription* BaseSession::initiator_description() const { return initiator_ ? local_description_.get() : remote_description_.get(); } -bool BaseSession::SetIdentity(rtc::SSLIdentity* identity) { - if (identity_) +bool BaseSession::SetCertificate( + const rtc::scoped_refptr& 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 @@ TransportProxy* BaseSession::GetOrCreateTransportProxy( 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 @@ void BaseSession::DestroyTransportProxy( Transport* BaseSession::CreateTransport(const std::string& content_name) { Transport* transport = new DtlsTransport( 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 79ccafd293..8d7aa21c22 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 @@ class TransportProxy : public sigslot::has_slots<> { // 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& certificate); bool SetLocalTransportDescription(const TransportDescription& description, ContentAction action, std::string* error_desc); @@ -315,14 +317,19 @@ class BaseSession : public sigslot::has_slots<>, 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& + 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& certificate); bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version); @@ -444,7 +451,7 @@ class BaseSession : public sigslot::has_slots<>, const std::string sid_; const std::string content_type_; bool initiator_; - rtc::SSLIdentity* identity_; + rtc::scoped_refptr certificate_; rtc::SSLProtocolVersion ssl_max_version_; rtc::scoped_ptr local_description_; rtc::scoped_ptr remote_description_; diff --git a/webrtc/p2p/base/transport.cc b/webrtc/p2p/base/transport.cc index 8b68a976b6..5f28c40e93 100644 --- a/webrtc/p2p/base/transport.cc +++ b/webrtc/p2p/base/transport.cc @@ -126,15 +126,18 @@ void Transport::SetIceRole(IceRole role) { worker_thread_->Invoke(Bind(&Transport::SetIceRole_w, this, role)); } -void Transport::SetIdentity(rtc::SSLIdentity* identity) { - worker_thread_->Invoke(Bind(&Transport::SetIdentity_w, this, identity)); +void Transport::SetCertificate( + const rtc::scoped_refptr& certificate) { + worker_thread_->Invoke(Bind(&Transport::SetCertificate_w, this, + certificate)); } -bool Transport::GetIdentity(rtc::SSLIdentity** identity) { +bool Transport::GetCertificate( + rtc::scoped_refptr* 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( - 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 4093240f3e..2e94c74436 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 @@ class Transport : public rtc::MessageHandler, 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 @@ class Transport : public rtc::MessageHandler, void SetChannelReceivingTimeout(int timeout_ms); // Must be called before applying local session description. - void SetIdentity(rtc::SSLIdentity* identity); + void SetCertificate( + const rtc::scoped_refptr& certificate); // Get a copy of the local identity provided by SetIdentity. - bool GetIdentity(rtc::SSLIdentity** identity); + bool GetCertificate(rtc::scoped_refptr* certificate); // Get a copy of the remote certificate in use by the specified channel. bool GetRemoteCertificate(rtc::SSLCertificate** cert); @@ -299,9 +301,11 @@ class Transport : public rtc::MessageHandler, return remote_description_.get(); } - virtual void SetIdentity_w(rtc::SSLIdentity* identity) {} + virtual void SetCertificate_w( + const rtc::scoped_refptr& certificate) {} - virtual bool GetIdentity_w(rtc::SSLIdentity** identity) { + virtual bool GetCertificate_w( + rtc::scoped_refptr* certificate) { return false; }