summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/nss_init.cc61
-rw-r--r--base/nss_init.h2
-rw-r--r--net/base/ssl_client_socket_nss.cc161
-rw-r--r--net/base/ssl_client_socket_nss.h2
-rw-r--r--net/base/ssl_test_util.cc145
-rw-r--r--net/base/ssl_test_util.h47
-rw-r--r--net/net_unittests.scons1
-rw-r--r--net/url_request/url_request_unittest.cc41
8 files changed, 435 insertions, 25 deletions
diff --git a/base/nss_init.cc b/base/nss_init.cc
index c8ba44b..f43bf3f 100644
--- a/base/nss_init.cc
+++ b/base/nss_init.cc
@@ -9,31 +9,88 @@
// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
// until NSS 3.12.2 comes out and we update to it.
#define Lock FOO_NSS_Lock
+#include <secmod.h>
#include <ssl.h>
#undef Lock
+#include "base/file_util.h"
#include "base/logging.h"
#include "base/singleton.h"
namespace {
+// Load nss's built-in root certs.
+// TODO(port): figure out a less hacky way to do this
+const char *possible_locations[] = {
+ "libnssckbi.so",
+ "/usr/lib32/nss/libnssckbi.so",
+ "/usr/lib/nss/libnssckbi.so",
+ "/usr/lib32/libnssckbi.so",
+ "/usr/lib/libnssckbi.so",
+ NULL
+};
+SECMODModule *InitDefaultRootCerts() {
+ int i;
+ for (i=0; possible_locations[i]; i++) {
+ if (possible_locations[i][0] == '/' && access(possible_locations[i], R_OK))
+ continue;
+ char modparams[1024];
+ snprintf(modparams, sizeof(modparams),
+ "name=\"Root Certs\" library=\"%s\"\n", possible_locations[i]);
+ SECMODModule *root = SECMOD_LoadUserModule(modparams, NULL, PR_FALSE);
+ if (root)
+ return root;
+ }
+ // Aw, snap. Can't find/load root cert shared library.
+ // This will make it hard to talk to anybody via https.
+ NOTREACHED();
+ return NULL;
+}
+
class NSSInitSingleton {
public:
NSSInitSingleton() {
+
+ // Initialize without using a persistant database (e.g. ~/.netscape)
CHECK(NSS_NoDB_Init(".") == SECSuccess);
- // Enable ciphers
+
+ root_ = InitDefaultRootCerts();
+
NSS_SetDomesticPolicy();
+
+ // Explicitly enable exactly those ciphers with keys of at least 80 bits
+ for (int i = 0; i < SSL_NumImplementedCiphers; i++) {
+ SSLCipherSuiteInfo info;
+ if (SSL_GetCipherSuiteInfo(SSL_ImplementedCiphers[i], &info,
+ sizeof(info)) == SECSuccess) {
+ SSL_CipherPrefSetDefault(SSL_ImplementedCiphers[i],
+ (info.effectiveKeyBits >= 80));
+ }
+ }
+
// Enable SSL
SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
+
+ // All other SSL options are set per-session by SSLClientSocket
}
~NSSInitSingleton() {
+ if (root_) {
+ SECMOD_UnloadUserModule(root_);
+ SECMOD_DestroyModule(root_);
+ root_ = NULL;
+ }
+
// Have to clear the cache, or NSS_Shutdown fails with SEC_ERROR_BUSY
SSL_ClearSessionCache();
SECStatus status = NSS_Shutdown();
- DCHECK(status == SECSuccess);
+ if (status != SECSuccess)
+ LOG(ERROR) << "NSS_Shutdown failed, leak? See "
+ "http://code.google.com/p/chromium/issues/detail?id=4609";
}
+ private:
+ SECMODModule *root_;
};
} // namespace
diff --git a/base/nss_init.h b/base/nss_init.h
index 181d292..ecfd0c6 100644
--- a/base/nss_init.h
+++ b/base/nss_init.h
@@ -5,6 +5,8 @@
#ifndef BASE_NSS_INIT_H_
#define BASE_NSS_INIT_H_
+#include <string>
+
namespace base {
// Initialize NSS if it isn't already initialized. This must be called before
diff --git a/net/base/ssl_client_socket_nss.cc b/net/base/ssl_client_socket_nss.cc
index c954ec9..f2f977b 100644
--- a/net/base/ssl_client_socket_nss.cc
+++ b/net/base/ssl_client_socket_nss.cc
@@ -6,10 +6,12 @@
#include <nspr.h>
#include <nss.h>
+#include <secerr.h>
// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
// until NSS 3.12.2 comes out and we update to it.
#define Lock FOO_NSS_Lock
#include <ssl.h>
+#include <sslerr.h>
#include <pk11pub.h>
#undef Lock
@@ -21,18 +23,16 @@
static const int kRecvBufferSize = 4096;
-/*
- * nss calls this if an incoming certificate is invalid.
- * TODO(port): expose to app via GetSSLInfo so it can put up
- * the appropriate GUI and retry with override if desired
- */
+// nss calls this if an incoming certificate is invalid.
static SECStatus
ownBadCertHandler(void * arg, PRFileDesc * socket)
{
PRErrorCode err = PR_GetError();
- LOG(ERROR) << "server certificate is invalid; NSS error code " << err;
- // Return SECSuccess to override the problem, SECFailure to let the original function fail
- return SECSuccess; /* override, say it's OK. */
+ LOG(INFO) << "server certificate is invalid; NSS error code " << err;
+ // Return SECSuccess to override the problem,
+ // or SECFailure to let the original function fail
+ // Chromium wants it to fail here, and may retry it later.
+ return SECFailure;
}
@@ -44,6 +44,7 @@ namespace net {
#define EnterFunction(x)
#define LeaveFunction(x)
#define GotoState(s) next_state_ = s
+#define LogData(s, len)
#else
#define EnterFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
" enter " << x << "; next_state " << next_state_
@@ -51,8 +52,79 @@ namespace net {
" leave " << x << "; next_state " << next_state_
#define GotoState(s) do { LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
" jump to state " << s; next_state_ = s; } while (0)
+#define LogData(s, len) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
+ " data [" << std::string(s, len) << "]";
+
#endif
+namespace {
+
+int NetErrorFromNSPRError(PRErrorCode err) {
+ // TODO(port): fill this out as we learn what's important
+ switch (err) {
+ case PR_WOULD_BLOCK_ERROR:
+ return ERR_IO_PENDING;
+ case SSL_ERROR_NO_CYPHER_OVERLAP:
+ return ERR_SSL_VERSION_OR_CIPHER_MISMATCH;
+ case SSL_ERROR_BAD_CERT_DOMAIN:
+ return ERR_CERT_COMMON_NAME_INVALID;
+ case SEC_ERROR_EXPIRED_CERTIFICATE:
+ return ERR_CERT_DATE_INVALID;
+ case SEC_ERROR_BAD_SIGNATURE:
+ return ERR_CERT_INVALID;
+ case SSL_ERROR_REVOKED_CERT_ALERT:
+ case SEC_ERROR_REVOKED_CERTIFICATE:
+ case SEC_ERROR_REVOKED_KEY:
+ return ERR_CERT_REVOKED;
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ return ERR_CERT_AUTHORITY_INVALID;
+
+ default: {
+ if (IS_SSL_ERROR(err)) {
+ LOG(WARNING) << "Unknown SSL error " << err <<
+ " mapped to net::ERR_SSL_PROTOCOL_ERROR";
+ return ERR_SSL_PROTOCOL_ERROR;
+ }
+ if (IS_SEC_ERROR(err)) {
+ // TODO(port): Probably not the best mapping
+ LOG(WARNING) << "Unknown SEC error " << err <<
+ " mapped to net::ERR_CERT_INVALID";
+ return ERR_CERT_INVALID;
+ }
+ LOG(WARNING) << "Unknown error " << err <<
+ " mapped to net::ERR_FAILED";
+ return ERR_FAILED;
+ }
+ }
+}
+
+// Shared with the Windows code. TODO(avi): merge to a common place
+int CertStatusFromNetError(int error) {
+ switch (error) {
+ case ERR_CERT_COMMON_NAME_INVALID:
+ return CERT_STATUS_COMMON_NAME_INVALID;
+ case ERR_CERT_DATE_INVALID:
+ return CERT_STATUS_DATE_INVALID;
+ case ERR_CERT_AUTHORITY_INVALID:
+ return CERT_STATUS_AUTHORITY_INVALID;
+ case ERR_CERT_NO_REVOCATION_MECHANISM:
+ return CERT_STATUS_NO_REVOCATION_MECHANISM;
+ case ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
+ return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
+ case ERR_CERT_REVOKED:
+ return CERT_STATUS_REVOKED;
+ case ERR_CERT_CONTAINS_ERRORS:
+ NOTREACHED();
+ // Falls through.
+ case ERR_CERT_INVALID:
+ return CERT_STATUS_INVALID;
+ default:
+ return 0;
+ }
+}
+
+} // namespace
+
bool SSLClientSocketNSS::nss_options_initialized_ = false;
SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket,
@@ -70,6 +142,7 @@ SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket,
user_callback_(NULL),
user_buf_(NULL),
user_buf_len_(0),
+ server_cert_status_(0),
completed_handshake_(false),
next_state_(STATE_NONE),
nss_fd_(NULL),
@@ -148,7 +221,7 @@ int SSLClientSocketNSS::Read(char* buf, int buf_len,
int rv = DoLoop(OK);
if (rv == ERR_IO_PENDING)
user_callback_ = callback;
- LeaveFunction("");
+ LeaveFunction(rv);
return rv;
}
@@ -167,14 +240,30 @@ int SSLClientSocketNSS::Write(const char* buf, int buf_len,
int rv = DoLoop(OK);
if (rv == ERR_IO_PENDING)
user_callback_ = callback;
- LeaveFunction("");
+ LeaveFunction(rv);
return rv;
}
void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
EnterFunction("");
- // TODO(port): implement!
ssl_info->Reset();
+ SSLChannelInfo channel_info;
+ SECStatus ok = SSL_GetChannelInfo(nss_fd_,
+ &channel_info, sizeof(channel_info));
+ if (ok == SECSuccess) {
+ SSLCipherSuiteInfo cipher_info;
+ ok = SSL_GetCipherSuiteInfo(channel_info.cipherSuite,
+ &cipher_info, sizeof(cipher_info));
+ if (ok == SECSuccess) {
+ ssl_info->security_bits = cipher_info.effectiveKeyBits;
+ } else {
+ ssl_info->security_bits = -1;
+ NOTREACHED();
+ }
+ }
+ ssl_info->cert_status = server_cert_status_;
+ // TODO(port): implement X509Certificate so we can set the cert field!
+ // CERTCertificate *nssCert = SSL_PeerCertificate(nss_fd_);
LeaveFunction("");
}
@@ -378,14 +467,32 @@ int SSLClientSocketNSS::DoConnectComplete(int result) {
if (rv != SECSuccess)
return ERR_UNEXPECTED;
+ // V2 compatible hello means no SNI, which would cause errors like
+ // "common name `mail.google.com' != requested host name `gmail.com'"
+ // so don't do V2 compatible hellos unless we're really using SSL2.
+ rv = SSL_OptionSet(nss_fd_, SSL_V2_COMPATIBLE_HELLO,
+ ssl_config_.ssl2_enabled);
+ if (rv != SECSuccess)
+ return ERR_UNEXPECTED;
+
rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.ssl3_enabled);
if (rv != SECSuccess)
return ERR_UNEXPECTED;
- rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.tls1_enabled);
+ rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
if (rv != SECSuccess)
return ERR_UNEXPECTED;
+#ifdef SSL_ENABLE_SESSION_TICKETS
+ // Support RFC 5077, if using NSS 3.12 or later
+ rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
+ if (rv != SECSuccess)
+ LOG(INFO) << "SSL_ENABLE_SESSION_TICKETS failed. Old system nss?";
+#else
+ // TODO(port): drop build-time support for old NSS once we're all on NSS 3.12
+ LOG(INFO) << "SSL_ENABLE_SESSION_TICKETS undefined. Old build system nss?";
+#endif
+
rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
if (rv != SECSuccess)
return ERR_UNEXPECTED;
@@ -407,31 +514,38 @@ int SSLClientSocketNSS::DoConnectComplete(int result) {
int SSLClientSocketNSS::DoHandshakeRead() {
EnterFunction("");
+ int net_error;
int rv = SSL_ForceHandshake(nss_fd_);
+
if (rv == SECSuccess) {
+ net_error = OK;
// there's a callback for this, too
completed_handshake_ = true;
// Indicate we're ready to handle I/O. Badly named?
GotoState(STATE_NONE);
- LeaveFunction("");
- return OK;
- }
- PRErrorCode prerr = PR_GetError();
- if (prerr == PR_WOULD_BLOCK_ERROR) {
- // at this point, it should have tried to send some bytes
- GotoState(STATE_HANDSHAKE_READ);
- LeaveFunction("");
- return ERR_IO_PENDING;
+ } else {
+ PRErrorCode prerr = PR_GetError();
+ net_error = NetErrorFromNSPRError(prerr);
+
+ // If not done, stay in this state
+ if (net_error == ERR_IO_PENDING) {
+ GotoState(STATE_HANDSHAKE_READ);
+ } else {
+ server_cert_status_ = CertStatusFromNetError(net_error);
+ LOG(ERROR) << "handshake failed; NSS error code " << prerr
+ << ", net_error " << net_error << ", server_cert_status " << server_cert_status_;
+ }
}
- // TODO: map rv to net error code properly
+
LeaveFunction("");
- return ERR_SSL_PROTOCOL_ERROR;
+ return net_error;
}
int SSLClientSocketNSS::DoPayloadRead() {
EnterFunction(user_buf_len_);
int rv = PR_Read(nss_fd_, user_buf_, user_buf_len_);
if (rv >= 0) {
+ LogData(user_buf_, rv);
user_buf_ = NULL;
LeaveFunction("");
return rv;
@@ -452,6 +566,7 @@ int SSLClientSocketNSS::DoPayloadWrite() {
EnterFunction(user_buf_len_);
int rv = PR_Write(nss_fd_, user_buf_, user_buf_len_);
if (rv >= 0) {
+ LogData(user_buf_, rv);
user_buf_ = NULL;
LeaveFunction("");
return rv;
diff --git a/net/base/ssl_client_socket_nss.h b/net/base/ssl_client_socket_nss.h
index 41098f3..5015e1e 100644
--- a/net/base/ssl_client_socket_nss.h
+++ b/net/base/ssl_client_socket_nss.h
@@ -76,6 +76,8 @@ class SSLClientSocketNSS : public SSLClientSocket {
char* user_buf_;
int user_buf_len_;
+ int server_cert_status_;
+
bool completed_handshake_;
enum State {
diff --git a/net/base/ssl_test_util.cc b/net/base/ssl_test_util.cc
new file mode 100644
index 0000000..3ce8f71
--- /dev/null
+++ b/net/base/ssl_test_util.cc
@@ -0,0 +1,145 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+#include <algorithm>
+
+#include "build/build_config.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#include <shlobj.h>
+#elif defined(OS_LINUX)
+
+#include <nspr.h>
+#include <nss.h>
+#include <secerr.h>
+// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
+// until NSS 3.12.2 comes out and we update to it.
+#define Lock FOO_NSS_Lock
+#include <ssl.h>
+#include <sslerr.h>
+#include <pk11pub.h>
+#undef Lock
+#include "base/nss_init.h"
+#endif
+
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+
+#include "net/base/ssl_test_util.h"
+
+// static
+const wchar_t SSLTestUtil::kDocRoot[] = L"chrome/test/data";
+const char SSLTestUtil::kHostName[] = "127.0.0.1";
+const int SSLTestUtil::kOKHTTPSPort = 9443;
+
+// The issuer name of the cert that should be trusted for the test to work.
+const wchar_t SSLTestUtil::kCertIssuerName[] = L"Test CA";
+
+#if defined(OS_LINUX)
+static CERTCertificate* LoadTemporaryCert(const std::wstring& filename) {
+ // TODO(port) Move to net/base so we can use net error codes,
+ // and maybe make this a static method of ssl_client_socket?
+
+ base::EnsureNSSInit();
+
+ std::string rawcert;
+ if (!file_util::ReadFileToString(filename, &rawcert)) {
+ LOG(ERROR) << "Can't load certificate " << filename;
+ return NULL;
+ }
+
+ // TODO(port): remove these const_casts after NSS 3.12.3 is released
+ CERTCertificate *cert;
+ cert = CERT_DecodeCertFromPackage(const_cast<char *>(rawcert.c_str()),
+ rawcert.length());
+ if (!cert) {
+ LOG(ERROR) << "Can't convert certificate " << filename;
+ return NULL;
+ }
+
+ CERTCertTrust trust;
+ int rv = CERT_DecodeTrustString(&trust, const_cast<char *>("TCu,Cu,Tu"));
+ if (rv != SECSuccess) {
+ LOG(ERROR) << "Can't decode trust string";
+ CERT_DestroyCertificate(cert);
+ return NULL;
+ }
+
+ rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust);
+ if (rv != SECSuccess) {
+ LOG(ERROR) << "Can't change trust for certificate " << filename;
+ CERT_DestroyCertificate(cert);
+ return NULL;
+ }
+
+ LOG(INFO) << "Loaded temporary certificate " << filename;
+ return cert;
+}
+#endif
+
+SSLTestUtil::SSLTestUtil() {
+ PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_);
+ cert_dir_ += L"/chrome/test/data/ssl/certificates/";
+ std::replace(cert_dir_.begin(), cert_dir_.end(),
+ L'/', file_util::kPathSeparator);
+
+#if defined(OS_LINUX)
+ cert_ = reinterpret_cast<PrivateCERTCertificate*>(
+ LoadTemporaryCert(GetRootCertPath()));
+ if (!cert_)
+ NOTREACHED();
+#endif
+
+ CheckCATrusted();
+}
+
+SSLTestUtil::~SSLTestUtil() {
+#if defined(OS_LINUX)
+ if (cert_)
+ CERT_DestroyCertificate(reinterpret_cast<CERTCertificate*>(cert_));
+#endif
+}
+
+std::wstring SSLTestUtil::GetRootCertPath() {
+ std::wstring path(cert_dir_);
+ file_util::AppendToPath(&path, L"root_ca_cert.crt");
+ return path;
+}
+
+std::wstring SSLTestUtil::GetOKCertPath() {
+ std::wstring path(cert_dir_);
+ file_util::AppendToPath(&path, L"ok_cert.pem");
+ return path;
+}
+
+void SSLTestUtil::CheckCATrusted() {
+// TODO(port): Port either this or LoadTemporaryCert to MacOSX.
+#if defined(OS_WIN)
+ HCERTSTORE cert_store = CertOpenSystemStore(NULL, L"ROOT");
+ if (!cert_store) {
+ FAIL() << " could not open trusted root CA store";
+ return;
+ }
+ PCCERT_CONTEXT cert =
+ CertFindCertificateInStore(cert_store,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ 0,
+ CERT_FIND_ISSUER_STR,
+ kCertIssuerName,
+ NULL);
+ if (cert)
+ CertFreeCertificateContext(cert);
+ CertCloseStore(cert_store, 0);
+
+ if (!cert) {
+ FAIL() << " TEST CONFIGURATION ERROR: you need to import the test ca "
+ "certificate to your trusted roots for this test to work. For more "
+ "info visit:\n"
+ "http://wiki.corp.google.com/twiki/bin/view/Main/ChromeUnitUITests\n";
+ }
+#endif
+}
diff --git a/net/base/ssl_test_util.h b/net/base/ssl_test_util.h
new file mode 100644
index 0000000..3502b9b
--- /dev/null
+++ b/net/base/ssl_test_util.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_SSL_TEST_UTIL_H_
+#define NET_BASE_SSL_TEST_UTIL_H_
+
+#include "build/build_config.h"
+
+#include <string>
+
+#include "base/path_service.h"
+
+class SSLTestUtil {
+ public:
+ SSLTestUtil();
+
+ ~SSLTestUtil();
+
+ std::wstring GetRootCertPath();
+
+ std::wstring GetOKCertPath();
+
+ // Where test data is kept in source tree
+ static const wchar_t kDocRoot[];
+
+ // Hostname to use for test server
+ static const char kHostName[];
+
+ // Port to use for test server
+ static const int kOKHTTPSPort;
+
+ // Issuer name of the cert that should be trusted for the test to work.
+ static const wchar_t kCertIssuerName[];
+
+ private:
+ void CheckCATrusted();
+
+ std::wstring cert_dir_;
+
+#if defined(OS_LINUX)
+ struct PrivateCERTCertificate;
+ PrivateCERTCertificate *cert_;
+#endif
+};
+
+#endif
diff --git a/net/net_unittests.scons b/net/net_unittests.scons
index 0879dee..3535850 100644
--- a/net/net_unittests.scons
+++ b/net/net_unittests.scons
@@ -54,6 +54,7 @@ input_files = [
'base/net_util_unittest.cc',
'base/registry_controlled_domain_unittest.cc',
'base/run_all_unittests.cc',
+ 'base/ssl_test_util.cc',
'base/ssl_client_socket_unittest.cc',
'base/tcp_client_socket_unittest.cc',
'base/telnet_server_unittest.cc',
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 05686e6..df7b98b 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -4,9 +4,13 @@
#include "net/url_request/url_request_unittest.h"
+#include "build/build_config.h"
+
#if defined(OS_WIN)
#include <windows.h>
#include <shlobj.h>
+#elif defined(OS_LINUX)
+#include "base/nss_init.h"
#endif
#include <algorithm>
@@ -18,10 +22,12 @@
#include "base/process_util.h"
#include "base/string_piece.h"
#include "base/string_util.h"
+#include "base/trace_event.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/net_module.h"
#include "net/base/net_util.h"
+#include "net/base/ssl_test_util.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
@@ -116,6 +122,41 @@ TEST_F(URLRequestTest, GetTest) {
#endif
}
+class HTTPSRequestTest : public testing::Test {
+ protected:
+ SSLTestUtil util_;
+};
+
+#if defined(OS_MACOSX)
+// TODO(port): support temporary root cert on mac
+#define MAYBE_HTTPSGetTest DISABLED_HTTPSGetTest
+#else
+#define MAYBE_HTTPSGetTest HTTPSGetTest
+#endif
+
+TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) {
+ base::TraceLog::StartTracing();
+ HTTPSTestServer https_server(util_.kHostName, util_.kOKHTTPSPort,
+ util_.kDocRoot, util_.GetOKCertPath());
+
+ TestDelegate d;
+ {
+ TestURLRequest r(https_server.TestServerPage(""), &d);
+
+ r.Start();
+ EXPECT_TRUE(r.is_pending());
+
+ MessageLoop::current()->Run();
+
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_FALSE(d.received_data_before_response());
+ EXPECT_NE(0, d.bytes_received());
+ }
+#ifndef NDEBUG
+ DCHECK_EQ(url_request_metrics.object_count,0);
+#endif
+}
+
TEST_F(URLRequestTest, CancelTest) {
TestDelegate d;
{