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}
This commit is contained in:
@ -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<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();
|
||||
}
|
||||
|
||||
@ -656,7 +656,9 @@ class StatsCollectorTest : public testing::Test {
|
||||
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 @@ 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<cricket::FakeTransportChannel*>(
|
||||
transport->CreateChannel(channel_stats.component));
|
||||
|
||||
@ -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<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();
|
||||
}
|
||||
|
||||
|
||||
@ -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<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) {
|
||||
|
||||
@ -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<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 @@ 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<SessionDescriptionInterface> 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<SessionDescriptionInterface> 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<SessionDescriptionInterface> offer(CreateOffer());
|
||||
EXPECT_TRUE(offer == NULL);
|
||||
|
||||
@ -98,14 +98,14 @@ void WebRtcIdentityRequestObserver::OnSuccess(
|
||||
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 @@ 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<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 @@ 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<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()) {
|
||||
|
||||
@ -58,7 +58,8 @@ class WebRtcIdentityRequestObserver : public DtlsIdentityRequestObserver,
|
||||
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 @@ class WebRtcSessionDescriptionFactory : public rtc::MessageHandler,
|
||||
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 @@ class WebRtcSessionDescriptionFactory : public rtc::MessageHandler,
|
||||
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_;
|
||||
|
||||
@ -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>(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 @@ 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<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_;
|
||||
|
||||
@ -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 Base>
|
||||
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<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 @@ class DtlsTransport : public Base {
|
||||
~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 @@ 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<rtc::RTCCertificate> certificate_;
|
||||
rtc::SSLRole secure_role_;
|
||||
rtc::SSLProtocolVersion ssl_max_version_;
|
||||
rtc::scoped_ptr<rtc::SSLFingerprint> remote_fingerprint_;
|
||||
|
||||
@ -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>(
|
||||
rtc::SSLIdentity::Generate(name_, key_type)).Pass());
|
||||
}
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& 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<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 @@ 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<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 @@ 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<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 @@ 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<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 @@ 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<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 @@ TEST_F(DtlsTransportChannelTest, TestCertificatesAfterConnect) {
|
||||
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());
|
||||
}
|
||||
|
||||
@ -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<rtc::RTCCertificate>& 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<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 @@ 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<rtc::RTCCertificate> 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<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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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<rtc::RTCCertificate>& 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<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 @@ 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<P2PTransport>(
|
||||
signaling_thread(), worker_thread(), content_name, port_allocator(),
|
||||
identity_);
|
||||
certificate_);
|
||||
transport->SetChannelReceivingTimeout(ice_receiving_timeout_);
|
||||
return transport;
|
||||
}
|
||||
|
||||
@ -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<rtc::RTCCertificate>& 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<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 @@ class BaseSession : public sigslot::has_slots<>,
|
||||
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_;
|
||||
|
||||
@ -126,15 +126,18 @@ void Transport::SetIceRole(IceRole role) {
|
||||
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) {
|
||||
|
||||
@ -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<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 @@ class Transport : public rtc::MessageHandler,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user