diff --git a/DEPS b/DEPS index 9813c616b5..dded4ac495 100644 --- a/DEPS +++ b/DEPS @@ -119,6 +119,15 @@ deps = { # Needed by build/common.gypi. "tools/win/supalink": Var("chromium_trunk") + "/src/tools/win/supalink@" + Var("chromium_revision"), + + "net/third_party/nss": + Var("chromium_trunk") + "/src/net/third_party/nss@" + Var("chromium_revision"), + + "third_party/usrsctp/": + Var("chromium_trunk") + "/src/third_party/usrsctp@" + Var("chromium_revision"), + + "third_party/usrsctp/usrsctplib": + (Var("googlecode_url") % "sctp-refimpl") + "/trunk/KERN/usrsctp/usrsctplib@8723", } deps_os = { @@ -147,12 +156,6 @@ deps_os = { # NSS, for SSLClientSocketNSS. "third_party/nss": From("chromium_deps", "src/third_party/nss"), - - # TODO(fischman): delete this in favor of the copy in "ios" below, once the - # webrtc iOS bots are fixed to target_os=['ios'] in their .gclient - # https://code.google.com/p/webrtc/issues/detail?id=2152 - "net/third_party/nss": - Var("chromium_trunk") + "/src/net/third_party/nss@" + Var("chromium_revision"), }, "ios": { @@ -160,9 +163,6 @@ deps_os = { "third_party/nss": From("chromium_deps", "src/third_party/nss"), - "net/third_party/nss": - Var("chromium_trunk") + "/src/net/third_party/nss@" + Var("chromium_revision"), - # class-dump utility to generate header files for undocumented SDKs. "testing/iossim/third_party/class-dump": From("chromium_deps", "src/testing/iossim/third_party/class-dump"), @@ -175,10 +175,8 @@ deps_os = { "unix": { "third_party/gold": From("chromium_deps", "src/third_party/gold"), - - "third_party/openssl": - From("chromium_deps", "src/third_party/openssl"), }, + "android": { # Precompiled tools needed for Android test execution. Needed since we can't # compile them from source in WebRTC since they depend on Chromium's base. diff --git a/talk/app/webrtc/jsepsessiondescription_unittest.cc b/talk/app/webrtc/jsepsessiondescription_unittest.cc index e2b59fba20..671df36d96 100644 --- a/talk/app/webrtc/jsepsessiondescription_unittest.cc +++ b/talk/app/webrtc/jsepsessiondescription_unittest.cc @@ -32,6 +32,7 @@ #include "talk/base/gunit.h" #include "talk/base/helpers.h" #include "talk/base/scoped_ptr.h" +#include "talk/base/ssladapter.h" #include "talk/base/stringencode.h" #include "talk/p2p/base/candidate.h" #include "talk/p2p/base/constants.h" @@ -96,6 +97,14 @@ static cricket::SessionDescription* CreateCricketSessionDescription() { class JsepSessionDescriptionTest : public testing::Test { protected: + static void SetUpTestCase() { + talk_base::InitializeSSL(); + } + + static void TearDownTestCase() { + talk_base::CleanupSSL(); + } + virtual void SetUp() { int port = 1234; talk_base::SocketAddress address("127.0.0.1", port++); diff --git a/talk/app/webrtc/objctests/RTCPeerConnectionTest.mm b/talk/app/webrtc/objctests/RTCPeerConnectionTest.mm index 0ce8822fd1..55e738839a 100644 --- a/talk/app/webrtc/objctests/RTCPeerConnectionTest.mm +++ b/talk/app/webrtc/objctests/RTCPeerConnectionTest.mm @@ -39,6 +39,7 @@ #import "RTCVideoTrack.h" #include "talk/base/gunit.h" +#include "talk/base/ssladapter.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -229,8 +230,12 @@ @end - +// TODO(fischman): move {Initialize,Cleanup}SSL into alloc/dealloc of +// RTCPeerConnectionTest and avoid the appearance of RTCPeerConnectionTest being +// a TestBase since it's not. TEST(RTCPeerConnectionTest, SessionTest) { + talk_base::InitializeSSL(); RTCPeerConnectionTest *pcTest = [[RTCPeerConnectionTest alloc] init]; [pcTest testCompleteSession]; + talk_base::CleanupSSL(); } diff --git a/talk/app/webrtc/peerconnection_unittest.cc b/talk/app/webrtc/peerconnection_unittest.cc index 76d9cd73cf..edf79f5a75 100644 --- a/talk/app/webrtc/peerconnection_unittest.cc +++ b/talk/app/webrtc/peerconnection_unittest.cc @@ -40,6 +40,7 @@ #include "talk/app/webrtc/peerconnectioninterface.h" #include "talk/app/webrtc/test/fakeaudiocapturemodule.h" #include "talk/app/webrtc/test/fakeconstraints.h" +#include "talk/app/webrtc/test/fakedtlsidentityservice.h" #include "talk/app/webrtc/test/fakevideotrackrenderer.h" #include "talk/app/webrtc/test/fakeperiodicvideocapturer.h" #include "talk/app/webrtc/test/mockpeerconnectionobservers.h" @@ -719,8 +720,19 @@ class JsepTestClient webrtc::PeerConnectionInterface::IceServer ice_server; ice_server.uri = "stun:stun.l.google.com:19302"; ice_servers.push_back(ice_server); + + // TODO(jiayl): we should always pass a FakeIdentityService so that DTLS + // is enabled by default like in Chrome (issue 2838). + FakeIdentityService* dtls_service = NULL; + bool dtls; + if (FindConstraint(constraints, + MediaConstraintsInterface::kEnableDtlsSrtp, + &dtls, + NULL) && dtls) { + dtls_service = new FakeIdentityService(); + } return peer_connection_factory()->CreatePeerConnection( - ice_servers, constraints, factory, NULL, this); + ice_servers, constraints, factory, dtls_service, this); } void HandleIncomingOffer(const std::string& msg) { diff --git a/talk/app/webrtc/peerconnectioninterface_unittest.cc b/talk/app/webrtc/peerconnectioninterface_unittest.cc index e47e5b17f8..f9d5e2eee8 100644 --- a/talk/app/webrtc/peerconnectioninterface_unittest.cc +++ b/talk/app/webrtc/peerconnectioninterface_unittest.cc @@ -32,6 +32,7 @@ #include "talk/app/webrtc/mediastreaminterface.h" #include "talk/app/webrtc/peerconnectioninterface.h" #include "talk/app/webrtc/test/fakeconstraints.h" +#include "talk/app/webrtc/test/fakedtlsidentityservice.h" #include "talk/app/webrtc/test/mockpeerconnectionobservers.h" #include "talk/app/webrtc/test/testsdpstrings.h" #include "talk/app/webrtc/videosource.h" @@ -258,9 +259,20 @@ class PeerConnectionInterfaceTest : public testing::Test { servers.push_back(server); port_allocator_factory_ = FakePortAllocatorFactory::Create(); + + // TODO(jiayl): we should always pass a FakeIdentityService so that DTLS + // is enabled by default like in Chrome (issue 2838). + FakeIdentityService* dtls_service = NULL; + bool dtls; + if (FindConstraint(constraints, + webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, + &dtls, + NULL) && dtls) { + dtls_service = new FakeIdentityService(); + } pc_ = pc_factory_->CreatePeerConnection(servers, constraints, port_allocator_factory_.get(), - NULL, + dtls_service, &observer_); ASSERT_TRUE(pc_.get() != NULL); observer_.SetPeerConnectionInterface(pc_.get()); diff --git a/talk/app/webrtc/test/fakedtlsidentityservice.h b/talk/app/webrtc/test/fakedtlsidentityservice.h index c70e0edb66..0c1a2a0c7c 100644 --- a/talk/app/webrtc/test/fakedtlsidentityservice.h +++ b/talk/app/webrtc/test/fakedtlsidentityservice.h @@ -33,32 +33,33 @@ static const char kRSA_PRIVATE_KEY_PEM[] = "-----BEGIN RSA PRIVATE KEY-----\n" - "MIICXQIBAAKBgQDCueE4a9hDMZ3sbVZdlXOz9ZA+cvzie3zJ9gXnT/BCt9P4b9HE\n" - "vD/tr73YBqD3Wr5ZWScmyGYF9EMn0r3rzBxv6oooLU5TdUvOm4rzUjkCLQaQML8o\n" - "NxXq+qW/j3zUKGikLhaaAl/amaX2zSWUsRQ1CpngQ3+tmDNH4/25TncNmQIDAQAB\n" - "AoGAUcuU0Id0k10fMjYHZk4mCPzot2LD2Tr4Aznl5vFMQipHzv7hhZtx2xzMSRcX\n" - "vG+Qr6VkbcUWHgApyWubvZXCh3+N7Vo2aYdMAQ8XqmFpBdIrL5CVdVfqFfEMlgEy\n" - "LSZNG5klnrIfl3c7zQVovLr4eMqyl2oGfAqPQz75+fecv1UCQQD6wNHch9NbAG1q\n" - "yuFEhMARB6gDXb+5SdzFjjtTWW5uJfm4DcZLoYyaIZm0uxOwsUKd0Rsma+oGitS1\n" - "CXmuqfpPAkEAxszyN3vIdpD44SREEtyKZBMNOk5pEIIGdbeMJC5/XHvpxww9xkoC\n" - "+39NbvUZYd54uT+rafbx4QZKc0h9xA/HlwJBAL37lYVWy4XpPv1olWCKi9LbUCqs\n" - "vvQtyD1N1BkEayy9TQRsO09WKOcmigRqsTJwOx7DLaTgokEuspYvhagWVPUCQE/y\n" - "0+YkTbYBD1Xbs9SyBKXCU6uDJRWSdO6aZi2W1XloC9gUwDMiSJjD1Wwt/YsyYPJ+\n" - "/Hyc5yFL2l0KZimW/vkCQQCjuZ/lPcH46EuzhdbRfumDOG5N3ld7UhGI1TIRy17W\n" - "dGF90cG33/L6BfS8Ll+fkkW/2AMRk8FDvF4CZi2nfW4L\n" + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n" + "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" + "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" + "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n" + "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n" + "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n" + "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n" + "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n" + "kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n" + "ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n" + "54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n" + "MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n" + "1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n" + "UCXiYxSsu20QNVw=\n" "-----END RSA PRIVATE KEY-----\n"; static const char kCERT_PEM[] = "-----BEGIN CERTIFICATE-----\n" - "MIIBmTCCAQICCQCPNJORW/M13DANBgkqhkiG9w0BAQUFADARMQ8wDQYDVQQDDAZ3\n" - "ZWJydGMwHhcNMTMwNjE0MjIzMDAxWhcNMTQwNjE0MjIzMDAxWjARMQ8wDQYDVQQD\n" - "DAZ3ZWJydGMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMK54Thr2EMxnext\n" - "Vl2Vc7P1kD5y/OJ7fMn2BedP8EK30/hv0cS8P+2vvdgGoPdavllZJybIZgX0QyfS\n" - "vevMHG/qiigtTlN1S86bivNSOQItBpAwvyg3Fer6pb+PfNQoaKQuFpoCX9qZpfbN\n" - "JZSxFDUKmeBDf62YM0fj/blOdw2ZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAECMt\n" - "UZb35H8TnjGx4XPzco/kbnurMLFFWcuve/DwTsuf10Ia9N4md8LY0UtgIgtyNqWc\n" - "ZwyRMwxONF6ty3wcaIiPbGqiAa55T3YRuPibkRmck9CjrmM9JAtyvqHnpHd2TsBD\n" - "qCV42aXS3onOXDQ1ibuWq0fr0//aj0wo4KV474c=\n" + "MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n" + "ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n" + "EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n" + "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" + "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" + "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n" + "VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n" + "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n" + "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n" "-----END CERTIFICATE-----\n"; using webrtc::DTLSIdentityRequestObserver; diff --git a/talk/base/common.h b/talk/base/common.h index e8e89dac19..381b6b5ac4 100644 --- a/talk/base/common.h +++ b/talk/base/common.h @@ -93,6 +93,11 @@ inline void Unused(const void*) {} namespace talk_base { + +// If a debugger is attached, triggers a debugger breakpoint. If a debugger is +// not attached, forces program termination. +void Break(); + // LogAssert writes information about an assertion to the log. It's called by // Assert (and from the ASSERT macro in debug mode) before any other action // is taken (e.g. breaking the debugger, abort()ing, etc.). @@ -113,15 +118,10 @@ void SetCustomAssertLogger(AssertLogger logger); } // namespace talk_base - #if ENABLE_DEBUG namespace talk_base { -// If a debugger is attached, triggers a debugger breakpoint. If a debugger is -// not attached, forces program termination. -void Break(); - inline bool Assert(bool result, const char* function, const char* file, int line, const char* expression) { if (!result) { diff --git a/talk/base/helpers_unittest.cc b/talk/base/helpers_unittest.cc index 0fe1d5b36e..c2cfdb193d 100644 --- a/talk/base/helpers_unittest.cc +++ b/talk/base/helpers_unittest.cc @@ -29,14 +29,26 @@ #include "talk/base/gunit.h" #include "talk/base/helpers.h" +#include "talk/base/ssladapter.h" namespace talk_base { -TEST(RandomTest, TestCreateRandomId) { +class RandomTest : public testing::Test { + public: + static void SetUpTestCase() { + talk_base::InitializeSSL(); + } + + static void TearDownTestCase() { + talk_base::CleanupSSL(); + } +}; + +TEST_F(RandomTest, TestCreateRandomId) { CreateRandomId(); } -TEST(RandomTest, TestCreateRandomDouble) { +TEST_F(RandomTest, TestCreateRandomDouble) { for (int i = 0; i < 100; ++i) { double r = CreateRandomDouble(); EXPECT_GE(r, 0.0); @@ -44,11 +56,11 @@ TEST(RandomTest, TestCreateRandomDouble) { } } -TEST(RandomTest, TestCreateNonZeroRandomId) { +TEST_F(RandomTest, TestCreateNonZeroRandomId) { EXPECT_NE(0U, CreateRandomNonZeroId()); } -TEST(RandomTest, TestCreateRandomString) { +TEST_F(RandomTest, TestCreateRandomString) { std::string random = CreateRandomString(256); EXPECT_EQ(256U, random.size()); std::string random2; @@ -57,7 +69,7 @@ TEST(RandomTest, TestCreateRandomString) { EXPECT_EQ(256U, random2.size()); } -TEST(RandomTest, TestCreateRandomForTest) { +TEST_F(RandomTest, TestCreateRandomForTest) { // Make sure we get the output we expect. SetRandomTestMode(true); EXPECT_EQ(2154761789U, CreateRandomId()); diff --git a/talk/base/nssidentity.cc b/talk/base/nssidentity.cc index 7bacb44461..05c82de8a6 100644 --- a/talk/base/nssidentity.cc +++ b/talk/base/nssidentity.cc @@ -48,6 +48,7 @@ #include "talk/base/logging.h" #include "talk/base/helpers.h" #include "talk/base/nssstreamadapter.h" +#include "talk/base/safe_conversions.h" namespace talk_base { @@ -143,7 +144,7 @@ NSSCertificate *NSSCertificate::FromPEMString(const std::string &pem_string) { SECItem der_cert; der_cert.data = reinterpret_cast(const_cast( der.data())); - der_cert.len = der.size(); + der_cert.len = checked_cast(der.size()); CERTCertificate *cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE); @@ -472,10 +473,9 @@ SSLIdentity* NSSIdentity::FromPEMStrings(const std::string& private_key, return NULL; SECItem private_key_item; - private_key_item.data = - reinterpret_cast( - const_cast(private_key_der.c_str())); - private_key_item.len = private_key_der.size(); + private_key_item.data = reinterpret_cast( + const_cast(private_key_der.c_str())); + private_key_item.len = checked_cast(private_key_der.size()); const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | KU_DIGITAL_SIGNATURE; diff --git a/talk/base/nssstreamadapter.cc b/talk/base/nssstreamadapter.cc index acddb672b4..8965a6830f 100644 --- a/talk/base/nssstreamadapter.cc +++ b/talk/base/nssstreamadapter.cc @@ -53,6 +53,7 @@ #endif #include "talk/base/nssidentity.h" +#include "talk/base/safe_conversions.h" #include "talk/base/thread.h" namespace talk_base { @@ -86,7 +87,8 @@ static const SrtpCipherMapEntry kSrtpCipherMap[] = { // Implementation of NSPR methods static PRStatus StreamClose(PRFileDesc *socket) { - // Noop + ASSERT(!socket->lower); + socket->dtor(socket); return PR_SUCCESS; } @@ -96,7 +98,7 @@ static PRInt32 StreamRead(PRFileDesc *socket, void *buf, PRInt32 length) { int error; StreamResult result = stream->Read(buf, length, &read, &error); if (result == SR_SUCCESS) { - return read; + return checked_cast(read); } if (result == SR_EOS) { @@ -119,7 +121,7 @@ static PRInt32 StreamWrite(PRFileDesc *socket, const void *buf, int error; StreamResult result = stream->Write(buf, length, &written, &error); if (result == SR_SUCCESS) { - return written; + return checked_cast(written); } if (result == SR_BLOCK) { @@ -437,7 +439,7 @@ bool NSSStreamAdapter::Init() { LOG(LS_ERROR) << "Error disabling false start"; return false; } - + ssl_fd_ = ssl_fd; return true; @@ -515,7 +517,7 @@ int NSSStreamAdapter::BeginSSL() { SSL_LIBRARY_VERSION_TLS_1_1 : SSL_LIBRARY_VERSION_TLS_1_0; vrange.max = SSL_LIBRARY_VERSION_TLS_1_1; - + rv = SSL_VersionRangeSet(ssl_fd_, &vrange); if (rv != SECSuccess) { Error("BeginSSL", -1, false); @@ -525,7 +527,9 @@ int NSSStreamAdapter::BeginSSL() { // SRTP #ifdef HAVE_DTLS_SRTP if (!srtp_ciphers_.empty()) { - rv = SSL_SetSRTPCiphers(ssl_fd_, &srtp_ciphers_[0], srtp_ciphers_.size()); + rv = SSL_SetSRTPCiphers( + ssl_fd_, &srtp_ciphers_[0], + checked_cast(srtp_ciphers_.size())); if (rv != SECSuccess) { Error("BeginSSL", -1, false); return -1; @@ -644,7 +648,7 @@ StreamResult NSSStreamAdapter::Read(void* data, size_t data_len, return SR_ERROR; } - PRInt32 rv = PR_Read(ssl_fd_, data, data_len); + PRInt32 rv = PR_Read(ssl_fd_, data, checked_cast(data_len)); if (rv == 0) { return SR_EOS; @@ -681,7 +685,7 @@ StreamResult NSSStreamAdapter::Write(const void* data, size_t data_len, case SSL_CONNECTED: break; - + case SSL_ERROR: case SSL_CLOSED: default: @@ -690,7 +694,7 @@ StreamResult NSSStreamAdapter::Write(const void* data, size_t data_len, return SR_ERROR; } - PRInt32 rv = PR_Write(ssl_fd_, data, data_len); + PRInt32 rv = PR_Write(ssl_fd_, data, checked_cast(data_len)); // Error if (rv < 0) { @@ -879,11 +883,15 @@ bool NSSStreamAdapter::ExportKeyingMaterial(const std::string& label, bool use_context, uint8* result, size_t result_len) { - SECStatus rv = SSL_ExportKeyingMaterial(ssl_fd_, - label.c_str(), label.size(), - use_context, - context, context_len, - result, result_len); + SECStatus rv = SSL_ExportKeyingMaterial( + ssl_fd_, + label.c_str(), + checked_cast(label.size()), + use_context, + context, + checked_cast(context_len), + result, + checked_cast(result_len)); return rv == SECSuccess; } diff --git a/talk/base/safe_conversions.h b/talk/base/safe_conversions.h new file mode 100644 index 0000000000..d246d4ffce --- /dev/null +++ b/talk/base/safe_conversions.h @@ -0,0 +1,96 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Borrowed from Chromium's src/base/numerics/safe_conversions.h. + +#ifndef TALK_BASE_SAFE_CONVERSIONS_H_ +#define TALK_BASE_SAFE_CONVERSIONS_H_ + +#include + +#include "talk/base/common.h" +#include "talk/base/logging.h" +#include "talk/base/safe_conversions_impl.h" + +namespace talk_base { + +inline void Check(bool condition) { + if (!condition) { + LOG(LS_ERROR) << "CHECK failed."; + Break(); + // The program should have crashed at this point. + } +} + +// Convenience function that returns true if the supplied value is in range +// for the destination type. +template +inline bool IsValueInRangeForNumericType(Src value) { + return internal::RangeCheck(value) == internal::TYPE_VALID; +} + +// checked_cast<> is analogous to static_cast<> for numeric types, +// except that it CHECKs that the specified numeric conversion will not +// overflow or underflow. NaN source will always trigger a CHECK. +template +inline Dst checked_cast(Src value) { + Check(IsValueInRangeForNumericType(value)); + return static_cast(value); +} + +// saturated_cast<> is analogous to static_cast<> for numeric types, except +// that the specified numeric conversion will saturate rather than overflow or +// underflow. NaN assignment to an integral will trigger a CHECK condition. +template +inline Dst saturated_cast(Src value) { + // Optimization for floating point values, which already saturate. + if (std::numeric_limits::is_iec559) + return static_cast(value); + + switch (internal::RangeCheck(value)) { + case internal::TYPE_VALID: + return static_cast(value); + + case internal::TYPE_UNDERFLOW: + return std::numeric_limits::min(); + + case internal::TYPE_OVERFLOW: + return std::numeric_limits::max(); + + // Should fail only on attempting to assign NaN to a saturated integer. + case internal::TYPE_INVALID: + Check(false); + return std::numeric_limits::max(); + } + + Check(false); // NOTREACHED(); + return static_cast(value); +} + +} // namespace talk_base + +#endif // TALK_BASE_SAFE_CONVERSIONS_H_ diff --git a/talk/base/safe_conversions_impl.h b/talk/base/safe_conversions_impl.h new file mode 100644 index 0000000000..391e5966b9 --- /dev/null +++ b/talk/base/safe_conversions_impl.h @@ -0,0 +1,205 @@ +/* + * libjingle + * Copyright 2014, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Borrowed from Chromium's src/base/numerics/safe_conversions_impl.h. + +#ifndef TALK_BASE_SAFE_CONVERSIONS_IMPL_H_ +#define TALK_BASE_SAFE_CONVERSIONS_IMPL_H_ + +#include + +namespace talk_base { +namespace internal { + +enum DstSign { + DST_UNSIGNED, + DST_SIGNED +}; + +enum SrcSign { + SRC_UNSIGNED, + SRC_SIGNED +}; + +enum DstRange { + OVERLAPS_RANGE, + CONTAINS_RANGE +}; + +// Helper templates to statically determine if our destination type can contain +// all values represented by the source type. + +template ::is_signed ? + DST_SIGNED : DST_UNSIGNED, + SrcSign IsSrcSigned = std::numeric_limits::is_signed ? + SRC_SIGNED : SRC_UNSIGNED> +struct StaticRangeCheck {}; + +template +struct StaticRangeCheck { + typedef std::numeric_limits DstLimits; + typedef std::numeric_limits SrcLimits; + // Compare based on max_exponent, which we must compute for integrals. + static const size_t kDstMaxExponent = DstLimits::is_iec559 ? + DstLimits::max_exponent : + (sizeof(Dst) * 8 - 1); + static const size_t kSrcMaxExponent = SrcLimits::is_iec559 ? + SrcLimits::max_exponent : + (sizeof(Src) * 8 - 1); + static const DstRange value = kDstMaxExponent >= kSrcMaxExponent ? + CONTAINS_RANGE : OVERLAPS_RANGE; +}; + +template +struct StaticRangeCheck { + static const DstRange value = sizeof(Dst) >= sizeof(Src) ? + CONTAINS_RANGE : OVERLAPS_RANGE; +}; + +template +struct StaticRangeCheck { + typedef std::numeric_limits DstLimits; + typedef std::numeric_limits SrcLimits; + // Compare based on max_exponent, which we must compute for integrals. + static const size_t kDstMaxExponent = DstLimits::is_iec559 ? + DstLimits::max_exponent : + (sizeof(Dst) * 8 - 1); + static const size_t kSrcMaxExponent = sizeof(Src) * 8; + static const DstRange value = kDstMaxExponent >= kSrcMaxExponent ? + CONTAINS_RANGE : OVERLAPS_RANGE; +}; + +template +struct StaticRangeCheck { + static const DstRange value = OVERLAPS_RANGE; +}; + + +enum RangeCheckResult { + TYPE_VALID = 0, // Value can be represented by the destination type. + TYPE_UNDERFLOW = 1, // Value would overflow. + TYPE_OVERFLOW = 2, // Value would underflow. + TYPE_INVALID = 3 // Source value is invalid (i.e. NaN). +}; + +// This macro creates a RangeCheckResult from an upper and lower bound +// check by taking advantage of the fact that only NaN can be out of range in +// both directions at once. +#define BASE_NUMERIC_RANGE_CHECK_RESULT(is_in_upper_bound, is_in_lower_bound) \ + RangeCheckResult(((is_in_upper_bound) ? 0 : TYPE_OVERFLOW) | \ + ((is_in_lower_bound) ? 0 : TYPE_UNDERFLOW)) + +template ::is_signed ? + DST_SIGNED : DST_UNSIGNED, + SrcSign IsSrcSigned = std::numeric_limits::is_signed ? + SRC_SIGNED : SRC_UNSIGNED, + DstRange IsSrcRangeContained = StaticRangeCheck::value> +struct RangeCheckImpl {}; + +// The following templates are for ranges that must be verified at runtime. We +// split it into checks based on signedness to avoid confusing casts and +// compiler warnings on signed an unsigned comparisons. + +// Dst range always contains the result: nothing to check. +template +struct RangeCheckImpl { + static RangeCheckResult Check(Src value) { + return TYPE_VALID; + } +}; + +// Signed to signed narrowing. +template +struct RangeCheckImpl { + static RangeCheckResult Check(Src value) { + typedef std::numeric_limits DstLimits; + return DstLimits::is_iec559 ? + BASE_NUMERIC_RANGE_CHECK_RESULT( + value <= static_cast(DstLimits::max()), + value >= static_cast(DstLimits::max() * -1)) : + BASE_NUMERIC_RANGE_CHECK_RESULT( + value <= static_cast(DstLimits::max()), + value >= static_cast(DstLimits::min())); + } +}; + +// Unsigned to unsigned narrowing. +template +struct RangeCheckImpl { + static RangeCheckResult Check(Src value) { + typedef std::numeric_limits DstLimits; + return BASE_NUMERIC_RANGE_CHECK_RESULT( + value <= static_cast(DstLimits::max()), true); + } +}; + +// Unsigned to signed. +template +struct RangeCheckImpl { + static RangeCheckResult Check(Src value) { + typedef std::numeric_limits DstLimits; + return sizeof(Dst) > sizeof(Src) ? TYPE_VALID : + BASE_NUMERIC_RANGE_CHECK_RESULT( + value <= static_cast(DstLimits::max()), true); + } +}; + +// Signed to unsigned. +template +struct RangeCheckImpl { + static RangeCheckResult Check(Src value) { + typedef std::numeric_limits DstLimits; + typedef std::numeric_limits SrcLimits; + // Compare based on max_exponent, which we must compute for integrals. + static const size_t kDstMaxExponent = sizeof(Dst) * 8; + static const size_t kSrcMaxExponent = SrcLimits::is_iec559 ? + SrcLimits::max_exponent : + (sizeof(Src) * 8 - 1); + return (kDstMaxExponent >= kSrcMaxExponent) ? + BASE_NUMERIC_RANGE_CHECK_RESULT(true, value >= static_cast(0)) : + BASE_NUMERIC_RANGE_CHECK_RESULT( + value <= static_cast(DstLimits::max()), + value >= static_cast(0)); + } +}; + +template +inline RangeCheckResult RangeCheck(Src value) { + COMPILE_ASSERT(std::numeric_limits::is_specialized, + argument_must_be_numeric); + COMPILE_ASSERT(std::numeric_limits::is_specialized, + result_must_be_numeric); + return RangeCheckImpl::Check(value); +} + +} // namespace internal +} // namespace talk_base + +#endif // TALK_BASE_SAFE_CONVERSIONS_IMPL_H_ diff --git a/talk/base/sslidentity_unittest.cc b/talk/base/sslidentity_unittest.cc index b63b8b9d43..fdb165c9f6 100644 --- a/talk/base/sslidentity_unittest.cc +++ b/talk/base/sslidentity_unittest.cc @@ -177,32 +177,33 @@ TEST_F(SSLIdentityTest, DigestSHA512) { TEST_F(SSLIdentityTest, FromPEMStrings) { static const char kRSA_PRIVATE_KEY_PEM[] = "-----BEGIN RSA PRIVATE KEY-----\n" - "MIICXQIBAAKBgQDCueE4a9hDMZ3sbVZdlXOz9ZA+cvzie3zJ9gXnT/BCt9P4b9HE\n" - "vD/tr73YBqD3Wr5ZWScmyGYF9EMn0r3rzBxv6oooLU5TdUvOm4rzUjkCLQaQML8o\n" - "NxXq+qW/j3zUKGikLhaaAl/amaX2zSWUsRQ1CpngQ3+tmDNH4/25TncNmQIDAQAB\n" - "AoGAUcuU0Id0k10fMjYHZk4mCPzot2LD2Tr4Aznl5vFMQipHzv7hhZtx2xzMSRcX\n" - "vG+Qr6VkbcUWHgApyWubvZXCh3+N7Vo2aYdMAQ8XqmFpBdIrL5CVdVfqFfEMlgEy\n" - "LSZNG5klnrIfl3c7zQVovLr4eMqyl2oGfAqPQz75+fecv1UCQQD6wNHch9NbAG1q\n" - "yuFEhMARB6gDXb+5SdzFjjtTWW5uJfm4DcZLoYyaIZm0uxOwsUKd0Rsma+oGitS1\n" - "CXmuqfpPAkEAxszyN3vIdpD44SREEtyKZBMNOk5pEIIGdbeMJC5/XHvpxww9xkoC\n" - "+39NbvUZYd54uT+rafbx4QZKc0h9xA/HlwJBAL37lYVWy4XpPv1olWCKi9LbUCqs\n" - "vvQtyD1N1BkEayy9TQRsO09WKOcmigRqsTJwOx7DLaTgokEuspYvhagWVPUCQE/y\n" - "0+YkTbYBD1Xbs9SyBKXCU6uDJRWSdO6aZi2W1XloC9gUwDMiSJjD1Wwt/YsyYPJ+\n" - "/Hyc5yFL2l0KZimW/vkCQQCjuZ/lPcH46EuzhdbRfumDOG5N3ld7UhGI1TIRy17W\n" - "dGF90cG33/L6BfS8Ll+fkkW/2AMRk8FDvF4CZi2nfW4L\n" + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n" + "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" + "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" + "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n" + "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n" + "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n" + "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n" + "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n" + "kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n" + "ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n" + "54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n" + "MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n" + "1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n" + "UCXiYxSsu20QNVw=\n" "-----END RSA PRIVATE KEY-----\n"; static const char kCERT_PEM[] = "-----BEGIN CERTIFICATE-----\n" - "MIIBmTCCAQICCQCPNJORW/M13DANBgkqhkiG9w0BAQUFADARMQ8wDQYDVQQDDAZ3\n" - "ZWJydGMwHhcNMTMwNjE0MjIzMDAxWhcNMTQwNjE0MjIzMDAxWjARMQ8wDQYDVQQD\n" - "DAZ3ZWJydGMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMK54Thr2EMxnext\n" - "Vl2Vc7P1kD5y/OJ7fMn2BedP8EK30/hv0cS8P+2vvdgGoPdavllZJybIZgX0QyfS\n" - "vevMHG/qiigtTlN1S86bivNSOQItBpAwvyg3Fer6pb+PfNQoaKQuFpoCX9qZpfbN\n" - "JZSxFDUKmeBDf62YM0fj/blOdw2ZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAECMt\n" - "UZb35H8TnjGx4XPzco/kbnurMLFFWcuve/DwTsuf10Ia9N4md8LY0UtgIgtyNqWc\n" - "ZwyRMwxONF6ty3wcaIiPbGqiAa55T3YRuPibkRmck9CjrmM9JAtyvqHnpHd2TsBD\n" - "qCV42aXS3onOXDQ1ibuWq0fr0//aj0wo4KV474c=\n" + "MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n" + "ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n" + "EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n" + "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" + "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" + "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n" + "VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n" + "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n" + "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n" "-----END CERTIFICATE-----\n"; talk_base::scoped_ptr identity( diff --git a/talk/base/sslstreamadapter_unittest.cc b/talk/base/sslstreamadapter_unittest.cc index 5cc4bfda73..d489221954 100644 --- a/talk/base/sslstreamadapter_unittest.cc +++ b/talk/base/sslstreamadapter_unittest.cc @@ -49,32 +49,33 @@ static int kExporterContextLen = sizeof(kExporterContext); static const char kRSA_PRIVATE_KEY_PEM[] = "-----BEGIN RSA PRIVATE KEY-----\n" - "MIICXQIBAAKBgQDCueE4a9hDMZ3sbVZdlXOz9ZA+cvzie3zJ9gXnT/BCt9P4b9HE\n" - "vD/tr73YBqD3Wr5ZWScmyGYF9EMn0r3rzBxv6oooLU5TdUvOm4rzUjkCLQaQML8o\n" - "NxXq+qW/j3zUKGikLhaaAl/amaX2zSWUsRQ1CpngQ3+tmDNH4/25TncNmQIDAQAB\n" - "AoGAUcuU0Id0k10fMjYHZk4mCPzot2LD2Tr4Aznl5vFMQipHzv7hhZtx2xzMSRcX\n" - "vG+Qr6VkbcUWHgApyWubvZXCh3+N7Vo2aYdMAQ8XqmFpBdIrL5CVdVfqFfEMlgEy\n" - "LSZNG5klnrIfl3c7zQVovLr4eMqyl2oGfAqPQz75+fecv1UCQQD6wNHch9NbAG1q\n" - "yuFEhMARB6gDXb+5SdzFjjtTWW5uJfm4DcZLoYyaIZm0uxOwsUKd0Rsma+oGitS1\n" - "CXmuqfpPAkEAxszyN3vIdpD44SREEtyKZBMNOk5pEIIGdbeMJC5/XHvpxww9xkoC\n" - "+39NbvUZYd54uT+rafbx4QZKc0h9xA/HlwJBAL37lYVWy4XpPv1olWCKi9LbUCqs\n" - "vvQtyD1N1BkEayy9TQRsO09WKOcmigRqsTJwOx7DLaTgokEuspYvhagWVPUCQE/y\n" - "0+YkTbYBD1Xbs9SyBKXCU6uDJRWSdO6aZi2W1XloC9gUwDMiSJjD1Wwt/YsyYPJ+\n" - "/Hyc5yFL2l0KZimW/vkCQQCjuZ/lPcH46EuzhdbRfumDOG5N3ld7UhGI1TIRy17W\n" - "dGF90cG33/L6BfS8Ll+fkkW/2AMRk8FDvF4CZi2nfW4L\n" + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n" + "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" + "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" + "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n" + "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n" + "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n" + "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n" + "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n" + "kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n" + "ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n" + "54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n" + "MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n" + "1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n" + "UCXiYxSsu20QNVw=\n" "-----END RSA PRIVATE KEY-----\n"; static const char kCERT_PEM[] = "-----BEGIN CERTIFICATE-----\n" - "MIIBmTCCAQICCQCPNJORW/M13DANBgkqhkiG9w0BAQUFADARMQ8wDQYDVQQDDAZ3\n" - "ZWJydGMwHhcNMTMwNjE0MjIzMDAxWhcNMTQwNjE0MjIzMDAxWjARMQ8wDQYDVQQD\n" - "DAZ3ZWJydGMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMK54Thr2EMxnext\n" - "Vl2Vc7P1kD5y/OJ7fMn2BedP8EK30/hv0cS8P+2vvdgGoPdavllZJybIZgX0QyfS\n" - "vevMHG/qiigtTlN1S86bivNSOQItBpAwvyg3Fer6pb+PfNQoaKQuFpoCX9qZpfbN\n" - "JZSxFDUKmeBDf62YM0fj/blOdw2ZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAECMt\n" - "UZb35H8TnjGx4XPzco/kbnurMLFFWcuve/DwTsuf10Ia9N4md8LY0UtgIgtyNqWc\n" - "ZwyRMwxONF6ty3wcaIiPbGqiAa55T3YRuPibkRmck9CjrmM9JAtyvqHnpHd2TsBD\n" - "qCV42aXS3onOXDQ1ibuWq0fr0//aj0wo4KV474c=\n" + "MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n" + "ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n" + "EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n" + "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" + "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" + "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n" + "VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n" + "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n" + "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n" "-----END CERTIFICATE-----\n"; #define MAYBE_SKIP_TEST(feature) \ @@ -208,13 +209,16 @@ class SSLStreamAdapterTestBase : public testing::Test, ~SSLStreamAdapterTestBase() { // Put it back for the next test. talk_base::SetRandomTestMode(false); - talk_base::CleanupSSL(); } static void SetUpTestCase() { talk_base::InitializeSSL(); } + static void TearDownTestCase() { + talk_base::CleanupSSL(); + } + // Recreate the client/server identities with the specified validity period. // |not_before| and |not_after| are offsets from the current time in number // of seconds. diff --git a/talk/build/common.gypi b/talk/build/common.gypi index 50acb39ea9..4c762d1ddf 100644 --- a/talk/build/common.gypi +++ b/talk/build/common.gypi @@ -101,11 +101,10 @@ ['OS=="ios"', { 'defines': [ 'IOS', - 'HAVE_NSS_SSL_H=1', - 'SSL_USE_NSS_RNG', ], - 'defines!': [ - 'HAVE_OPENSSL_SSL_H=1', + }, { + 'defines': [ + 'HAVE_SCTP', ], }], ['OS=="ios" or (OS=="mac" and target_arch!="ia32")', { @@ -118,11 +117,41 @@ 'HASH_NAMESPACE=__gnu_cxx', 'POSIX', 'DISABLE_DYNAMIC_CAST', - 'HAVE_OPENSSL_SSL_H=1', # The POSIX standard says we have to define this. '_REENTRANT', ], }], + # TODO(jiayl): collapse the following 5 defines into 2, one for NSS and + # one for OPENSSL, and update the relevant code. + ['use_openssl==1', { + 'defines': [ + 'SSL_USE_OPENSSL', + 'HAVE_OPENSSL_SSL_H', + ], + 'dependencies': [ + '<(DEPTH)/third_party/openssl/openssl.gyp:openssl', + ], + }, { + 'defines': [ + 'SSL_USE_NSS', + 'HAVE_NSS_SSL_H', + 'SSL_USE_NSS_RNG', + ], + 'conditions': [ + ['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', { + 'dependencies': [ + '<(DEPTH)/build/linux/system.gyp:ssl', + ], + }], + ['OS == "mac" or OS == "ios" or OS == "win"', { + 'dependencies': [ + '<(DEPTH)/net/third_party/nss/ssl.gyp:libssl', + '<(DEPTH)/third_party/nss/nss.gyp:nspr', + '<(DEPTH)/third_party/nss/nss.gyp:nss', + ], + }], + ], + }], ], }, # target_defaults } diff --git a/talk/libjingle.gyp b/talk/libjingle.gyp index 38a165be80..f5632b1658 100755 --- a/talk/libjingle.gyp +++ b/talk/libjingle.gyp @@ -27,7 +27,6 @@ { 'includes': ['build/common.gypi'], - 'conditions': [ ['os_posix == 1 and OS != "mac" and OS != "ios"', { 'conditions': [ @@ -546,13 +545,6 @@ 'xmpp/xmppthread.h', ], 'conditions': [ - ['OS=="mac" or OS=="ios" or OS=="win"', { - 'dependencies': [ - # The chromium copy of nss should NOT be used on platforms that - # have NSS as system libraries, such as linux. - '<(DEPTH)/third_party/nss/nss.gyp:nss', - ], - }], ['OS=="android"', { 'sources': [ 'base/ifaddrs-android.cc', @@ -713,11 +705,6 @@ 'base/unixfilesystem.h', ], 'conditions': [ - ['OS=="linux" or OS=="android"', { - 'dependencies': [ - '<(DEPTH)/third_party/openssl/openssl.gyp:openssl', - ], - }], ['OS!="ios"', { 'sources': [ 'base/openssladapter.cc', @@ -779,8 +766,14 @@ { 'target_name': 'libjingle_media', 'type': 'static_library', + 'include_dirs': [ + # TODO(jiayl): move this into the direct_dependent_settings of + # usrsctp.gyp. + '<(DEPTH)/third_party/usrsctp', + ], 'dependencies': [ '<(DEPTH)/third_party/libyuv/libyuv.gyp:libyuv', + '<(DEPTH)/third_party/usrsctp/usrsctp.gyp:usrsctplib', '<(webrtc_root)/modules/modules.gyp:video_capture_module', '<(webrtc_root)/modules/modules.gyp:video_render_module', '<(webrtc_root)/video_engine/video_engine.gyp:video_engine_core', @@ -847,9 +840,8 @@ 'media/devices/filevideocapturer.h', 'media/devices/videorendererfactory.h', 'media/other/linphonemediaengine.h', - # TODO(ronghuawu): Enable when SCTP is ready. - # 'media/sctp/sctpdataengine.cc', - # 'media/sctp/sctpdataengine.h', + 'media/sctp/sctpdataengine.cc', + 'media/sctp/sctpdataengine.h', 'media/webrtc/webrtccommon.h', 'media/webrtc/webrtcexport.h', 'media/webrtc/webrtcmediaengine.h', @@ -965,6 +957,13 @@ # libjpeg which pulls in libyuv which currently disabled. '../third_party/libyuv/include', ], + 'dependencies!': [ + '<(DEPTH)/third_party/usrsctp/usrsctp.gyp:usrsctplib', + ], + 'sources!': [ + 'media/sctp/sctpdataengine.cc', + 'media/sctp/sctpdataengine.h', + ], }], ['OS=="android"', { 'sources': [ @@ -989,10 +988,6 @@ '<(DEPTH)/testing/gtest/include', ], }, - 'defines': [ - # TODO(ronghuawu): enable SCTP when it's ready. - # 'HAVE_SCTP', - ], 'sources': [ 'p2p/base/asyncstuntcpsocket.cc', 'p2p/base/asyncstuntcpsocket.h', diff --git a/talk/libjingle_tests.gyp b/talk/libjingle_tests.gyp index 201052af13..9987ed8a49 100755 --- a/talk/libjingle_tests.gyp +++ b/talk/libjingle_tests.gyp @@ -279,6 +279,9 @@ 'media/base/videoengine_unittest.h', 'media/devices/dummydevicemanager_unittest.cc', 'media/devices/filevideocapturer_unittest.cc', + # TODO(jiayl): Enable the SCTP test once the memcheck and tsan bots + # failures are fixed (issue 2846). + #'media/sctp/sctpdataengine_unittest.cc', 'media/webrtc/webrtcpassthroughrender_unittest.cc', 'media/webrtc/webrtcvideocapturer_unittest.cc', # Omitted because depends on non-open-source testdata files. @@ -304,6 +307,11 @@ }, }, }], + ['OS=="ios"', { + 'sources!': [ + 'media/sctp/sctpdataengine_unittest.cc', + ], + }], ], }, # target libjingle_media_unittest { diff --git a/talk/media/base/rtpdataengine_unittest.cc b/talk/media/base/rtpdataengine_unittest.cc index 3c8318493b..640c18dbfc 100644 --- a/talk/media/base/rtpdataengine_unittest.cc +++ b/talk/media/base/rtpdataengine_unittest.cc @@ -31,6 +31,7 @@ #include "talk/base/gunit.h" #include "talk/base/helpers.h" #include "talk/base/scoped_ptr.h" +#include "talk/base/ssladapter.h" #include "talk/base/timing.h" #include "talk/media/base/constants.h" #include "talk/media/base/fakenetworkinterface.h" @@ -82,6 +83,14 @@ class FakeDataReceiver : public sigslot::has_slots<> { class RtpDataMediaChannelTest : public testing::Test { protected: + static void SetUpTestCase() { + talk_base::InitializeSSL(); + } + + static void TearDownTestCase() { + talk_base::CleanupSSL(); + } + virtual void SetUp() { // Seed needed for each test to satisfy expectations. iface_.reset(new cricket::FakeNetworkInterface()); diff --git a/talk/media/sctp/sctpdataengine.cc b/talk/media/sctp/sctpdataengine.cc index 03bbdcaa1f..37b17d3a51 100644 --- a/talk/media/sctp/sctpdataengine.cc +++ b/talk/media/sctp/sctpdataengine.cc @@ -35,6 +35,7 @@ #include "talk/base/buffer.h" #include "talk/base/helpers.h" #include "talk/base/logging.h" +#include "talk/base/safe_conversions.h" #include "talk/media/base/codec.h" #include "talk/media/base/constants.h" #include "talk/media/base/streamparams.h" @@ -560,7 +561,7 @@ bool SctpDataMediaChannel::SendData( send_res = usrsctp_sendv(sock_, payload.data(), static_cast(payload.length()), NULL, 0, &spa, - static_cast(sizeof(spa)), + talk_base::checked_cast(sizeof(spa)), SCTP_SENDV_SPA, 0); if (send_res < 0) { if (errno == EWOULDBLOCK) { @@ -919,15 +920,16 @@ bool SctpDataMediaChannel::SendQueuedStreamResets() { &reset_stream_buf[0]); resetp->srs_assoc_id = SCTP_ALL_ASSOC; resetp->srs_flags = SCTP_STREAM_RESET_INCOMING | SCTP_STREAM_RESET_OUTGOING; - resetp->srs_number_streams = num_streams; + resetp->srs_number_streams = talk_base::checked_cast(num_streams); int result_idx = 0; for (StreamSet::iterator it = queued_reset_streams_.begin(); it != queued_reset_streams_.end(); ++it) { resetp->srs_stream_list[result_idx++] = *it; } - int ret = usrsctp_setsockopt(sock_, IPPROTO_SCTP, SCTP_RESET_STREAMS, resetp, - reset_stream_buf.size()); + int ret = usrsctp_setsockopt( + sock_, IPPROTO_SCTP, SCTP_RESET_STREAMS, resetp, + talk_base::checked_cast(reset_stream_buf.size())); if (ret < 0) { LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to send a stream reset for " << num_streams << " streams"; diff --git a/talk/media/sctp/sctpdataengine_unittest.cc b/talk/media/sctp/sctpdataengine_unittest.cc index 6371300b53..650c785cb1 100644 --- a/talk/media/sctp/sctpdataengine_unittest.cc +++ b/talk/media/sctp/sctpdataengine_unittest.cc @@ -39,6 +39,7 @@ #include "talk/base/messagehandler.h" #include "talk/base/messagequeue.h" #include "talk/base/scoped_ptr.h" +#include "talk/base/ssladapter.h" #include "talk/base/thread.h" #include "talk/media/base/constants.h" #include "talk/media/base/mediachannel.h" @@ -215,6 +216,16 @@ class SignalChannelClosedReopener : public sigslot::has_slots<> { class SctpDataMediaChannelTest : public testing::Test, public sigslot::has_slots<> { protected: + // usrsctp uses the NSS random number generator on non-Android platforms, + // so we need to initialize SSL. + static void SetUpTestCase() { + talk_base::InitializeSSL(); + } + + static void TearDownTestCase() { + talk_base::CleanupSSL(); + } + virtual void SetUp() { engine_.reset(new cricket::SctpDataEngine()); }