Enable SCTP and use OPENSSL on Anroid and NSS on other platforms.

It includes unit test fixes to properly initialize SSL if DTLS or SSL random number generator is used in the tests.
The private key and certificate constant strings used in some tests are updated to be compatible with NSS.
A few potentially overflow type conversions caused compiling warning on Windows and they are fixed by importing and using Chromium's checked_cast, which aborts the program if overflow occurs.
It also fixes a leak in nssstreamadapter.cc by releasing the PRFileDesc* in StreamClose.

BUG=2253
R=fischman@webrtc.org, juberti@google.com, wu@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5459 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
jiayl@webrtc.org 2014-01-29 17:45:53 +00:00
parent 07e5196414
commit a576faf82a
20 changed files with 557 additions and 140 deletions

22
DEPS
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<unsigned char *>(const_cast<char *>(
der.data()));
der_cert.len = der.size();
der_cert.len = checked_cast<unsigned int>(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<unsigned char *>(
const_cast<char *>(private_key_der.c_str()));
private_key_item.len = private_key_der.size();
private_key_item.data = reinterpret_cast<unsigned char *>(
const_cast<char *>(private_key_der.c_str()));
private_key_item.len = checked_cast<unsigned int>(private_key_der.size());
const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT |
KU_DIGITAL_SIGNATURE;

View File

@ -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<PRInt32>(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<PRInt32>(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<unsigned int>(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<PRInt32>(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<PRInt32>(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<unsigned int>(label.size()),
use_context,
context,
checked_cast<unsigned int>(context_len),
result,
checked_cast<unsigned int>(result_len));
return rv == SECSuccess;
}

View File

@ -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 <limits>
#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 <typename Dst, typename Src>
inline bool IsValueInRangeForNumericType(Src value) {
return internal::RangeCheck<Dst>(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 <typename Dst, typename Src>
inline Dst checked_cast(Src value) {
Check(IsValueInRangeForNumericType<Dst>(value));
return static_cast<Dst>(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 <typename Dst, typename Src>
inline Dst saturated_cast(Src value) {
// Optimization for floating point values, which already saturate.
if (std::numeric_limits<Dst>::is_iec559)
return static_cast<Dst>(value);
switch (internal::RangeCheck<Dst>(value)) {
case internal::TYPE_VALID:
return static_cast<Dst>(value);
case internal::TYPE_UNDERFLOW:
return std::numeric_limits<Dst>::min();
case internal::TYPE_OVERFLOW:
return std::numeric_limits<Dst>::max();
// Should fail only on attempting to assign NaN to a saturated integer.
case internal::TYPE_INVALID:
Check(false);
return std::numeric_limits<Dst>::max();
}
Check(false); // NOTREACHED();
return static_cast<Dst>(value);
}
} // namespace talk_base
#endif // TALK_BASE_SAFE_CONVERSIONS_H_

View File

@ -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 <limits>
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 <typename Dst, typename Src,
DstSign IsDstSigned = std::numeric_limits<Dst>::is_signed ?
DST_SIGNED : DST_UNSIGNED,
SrcSign IsSrcSigned = std::numeric_limits<Src>::is_signed ?
SRC_SIGNED : SRC_UNSIGNED>
struct StaticRangeCheck {};
template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_SIGNED> {
typedef std::numeric_limits<Dst> DstLimits;
typedef std::numeric_limits<Src> 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 <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED> {
static const DstRange value = sizeof(Dst) >= sizeof(Src) ?
CONTAINS_RANGE : OVERLAPS_RANGE;
};
template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_UNSIGNED> {
typedef std::numeric_limits<Dst> DstLimits;
typedef std::numeric_limits<Src> 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 <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_SIGNED> {
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 <typename Dst,
typename Src,
DstSign IsDstSigned = std::numeric_limits<Dst>::is_signed ?
DST_SIGNED : DST_UNSIGNED,
SrcSign IsSrcSigned = std::numeric_limits<Src>::is_signed ?
SRC_SIGNED : SRC_UNSIGNED,
DstRange IsSrcRangeContained = StaticRangeCheck<Dst, Src>::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 <typename Dst, typename Src, DstSign IsDstSigned, SrcSign IsSrcSigned>
struct RangeCheckImpl<Dst, Src, IsDstSigned, IsSrcSigned, CONTAINS_RANGE> {
static RangeCheckResult Check(Src value) {
return TYPE_VALID;
}
};
// Signed to signed narrowing.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
static RangeCheckResult Check(Src value) {
typedef std::numeric_limits<Dst> DstLimits;
return DstLimits::is_iec559 ?
BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()),
value >= static_cast<Src>(DstLimits::max() * -1)) :
BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()),
value >= static_cast<Src>(DstLimits::min()));
}
};
// Unsigned to unsigned narrowing.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
static RangeCheckResult Check(Src value) {
typedef std::numeric_limits<Dst> DstLimits;
return BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()), true);
}
};
// Unsigned to signed.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
static RangeCheckResult Check(Src value) {
typedef std::numeric_limits<Dst> DstLimits;
return sizeof(Dst) > sizeof(Src) ? TYPE_VALID :
BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()), true);
}
};
// Signed to unsigned.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
static RangeCheckResult Check(Src value) {
typedef std::numeric_limits<Dst> DstLimits;
typedef std::numeric_limits<Src> 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<Src>(0)) :
BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()),
value >= static_cast<Src>(0));
}
};
template <typename Dst, typename Src>
inline RangeCheckResult RangeCheck(Src value) {
COMPILE_ASSERT(std::numeric_limits<Src>::is_specialized,
argument_must_be_numeric);
COMPILE_ASSERT(std::numeric_limits<Dst>::is_specialized,
result_must_be_numeric);
return RangeCheckImpl<Dst, Src>::Check(value);
}
} // namespace internal
} // namespace talk_base
#endif // TALK_BASE_SAFE_CONVERSIONS_IMPL_H_

View File

@ -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<SSLIdentity> identity(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<size_t>(payload.length()),
NULL, 0, &spa,
static_cast<socklen_t>(sizeof(spa)),
talk_base::checked_cast<socklen_t>(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<uint16_t>(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<socklen_t>(reset_stream_buf.size()));
if (ret < 0) {
LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to send a stream reset for "
<< num_streams << " streams";

View File

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