summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-02 19:49:48 +0000
committerdkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-02 19:49:48 +0000
commit78e8c3d710650acb48fd241a826d86ad22941c66 (patch)
tree49e63fb3431b9d225479c02c2e4335df0fbd43b7
parent9cf11c6589e6e24df310bf634155d90afd4def56 (diff)
downloadchromium_src-78e8c3d710650acb48fd241a826d86ad22941c66.zip
chromium_src-78e8c3d710650acb48fd241a826d86ad22941c66.tar.gz
chromium_src-78e8c3d710650acb48fd241a826d86ad22941c66.tar.bz2
For http://code.google.com/p/chromium/issues/detail?id=4510
Extract some UI SSL test code into new class SSLTestUtil to avoid duplication. Point nss at root certs so test_shell can talk to mail.google.com without warnings. Support ciphers needed to talk to testserver.py. Load temporary testing cert needed to run unit tests. Implement part of GetSSLInfo. Change URL in developer error message to point to chromium.org. Re-enable url_request_unittest.cc, which seems to have been disabled by mistake. Later changesets will implement x509 certificates for nss, finish GetSSLInfo support, and update chrome/browser/ssl_uitest.cc to use SSLTestUtil. Earlier version was committed as r6063, but was rolled back. Review URL: http://codereview.chromium.org/11249 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6233 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/nss_init.cc49
-rw-r--r--net/base/ssl_client_socket_nss.cc162
-rw-r--r--net/base/ssl_client_socket_nss.h2
-rw-r--r--net/base/ssl_test_util.cc144
-rw-r--r--net/base/ssl_test_util.h46
-rw-r--r--net/build/net_unittests.vcproj4
-rw-r--r--net/net.xcodeproj/project.pbxproj16
-rw-r--r--net/net_unittests.scons1
-rw-r--r--net/url_request/url_request_unittest.cc42
9 files changed, 436 insertions, 30 deletions
diff --git a/base/nss_init.cc b/base/nss_init.cc
index c8ba44b..df2beea 100644
--- a/base/nss_init.cc
+++ b/base/nss_init.cc
@@ -9,31 +9,76 @@
// 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.
+SECMODModule *InitDefaultRootCerts() {
+ const char* kModulePath = "libnssckbi.so";
+ char modparams[1024];
+ snprintf(modparams, sizeof(modparams),
+ "name=\"Root Certs\" library=\"%s\"", kModulePath);
+ 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/net/base/ssl_client_socket_nss.cc b/net/base/ssl_client_socket_nss.cc
index c954ec9..ef1d6b4 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,33 @@ int SSLClientSocketNSS::DoConnectComplete(int result) {
if (rv != SECSuccess)
return ERR_UNEXPECTED;
+ // SNI is enabled automatically if TLS is enabled -- as long as
+ // SSL_V2_COMPATIBLE_HELLO isn't.
+ // So don't do V2 compatible hellos unless we're really using SSL2,
+ // to avoid errors like
+ // "common name `mail.google.com' != requested host name `gmail.com'"
+ 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
+ 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
+ #error "You need to install NSS-3.12 or later to build chromium"
+#endif
+
rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
if (rv != SECSuccess)
return ERR_UNEXPECTED;
@@ -407,31 +515,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 +567,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
index e69de29..199bbbd 100644
--- a/net/base/ssl_test_util.cc
+++ b/net/base/ssl_test_util.cc
@@ -0,0 +1,144 @@
+// 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 <wincrypt.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 FilePath& filename) {
+ base::EnsureNSSInit();
+
+ std::string rawcert;
+ if (!file_util::ReadFileToString(filename.ToWStringHack(), &rawcert)) {
+ LOG(ERROR) << "Can't load certificate " << filename.ToWStringHack();
+ return NULL;
+ }
+
+ CERTCertificate *cert;
+ cert = CERT_DecodeCertFromPackage(const_cast<char *>(rawcert.c_str()),
+ rawcert.length());
+ if (!cert) {
+ LOG(ERROR) << "Can't convert certificate " << filename.ToWStringHack();
+ return NULL;
+ }
+
+ // TODO(port): remove this const_cast after NSS 3.12.3 is released
+ 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.ToWStringHack();
+ CERT_DestroyCertificate(cert);
+ return NULL;
+ }
+
+ LOG(INFO) << "Loaded temporary certificate " << filename.ToWStringHack();
+ return cert;
+}
+#endif
+
+SSLTestUtil::SSLTestUtil() {
+ PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_);
+ cert_dir_ = cert_dir_.Append(FILE_PATH_LITERAL("chrome"));
+ cert_dir_ = cert_dir_.Append(FILE_PATH_LITERAL("test"));
+ cert_dir_ = cert_dir_.Append(FILE_PATH_LITERAL("data"));
+ cert_dir_ = cert_dir_.Append(FILE_PATH_LITERAL("ssl"));
+ cert_dir_ = cert_dir_.Append(FILE_PATH_LITERAL("certificates"));
+
+#if defined(OS_LINUX)
+ cert_ = reinterpret_cast<PrivateCERTCertificate*>(
+ LoadTemporaryCert(GetRootCertPath()));
+ if (!cert_)
+ NOTREACHED();
+#endif
+}
+
+SSLTestUtil::~SSLTestUtil() {
+#if defined(OS_LINUX)
+ if (cert_)
+ CERT_DestroyCertificate(reinterpret_cast<CERTCertificate*>(cert_));
+#endif
+}
+
+FilePath SSLTestUtil::GetRootCertPath() {
+ FilePath path(cert_dir_);
+ path = path.Append(FILE_PATH_LITERAL("root_ca_cert.crt"));
+ return path;
+}
+
+FilePath SSLTestUtil::GetOKCertPath() {
+ FilePath path(cert_dir_);
+ path = path.Append(FILE_PATH_LITERAL("ok_cert.pem"));
+ return path;
+}
+
+bool 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) {
+ LOG(ERROR) << " could not open trusted root CA store";
+ return false;
+ }
+ 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) {
+ LOG(ERROR) << " 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://dev.chromium.org/developers/testing\n";
+ return false;
+ }
+#endif
+ return true;
+}
diff --git a/net/base/ssl_test_util.h b/net/base/ssl_test_util.h
index e69de29..a193742 100644
--- a/net/base/ssl_test_util.h
+++ b/net/base/ssl_test_util.h
@@ -0,0 +1,46 @@
+// 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 "base/path_service.h"
+
+class SSLTestUtil {
+ public:
+ SSLTestUtil();
+
+ ~SSLTestUtil();
+
+ FilePath GetRootCertPath();
+
+ FilePath 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[];
+
+ // Returns false if our test root certificate is not trusted.
+ bool CheckCATrusted();
+
+ private:
+ FilePath cert_dir_;
+
+#if defined(OS_LINUX)
+ struct PrivateCERTCertificate;
+ PrivateCERTCertificate *cert_;
+#endif
+};
+
+#endif
diff --git a/net/build/net_unittests.vcproj b/net/build/net_unittests.vcproj
index f92d227..1f5e71a 100644
--- a/net/build/net_unittests.vcproj
+++ b/net/build/net_unittests.vcproj
@@ -379,6 +379,10 @@
>
</File>
<File
+ RelativePath="..\base\ssl_test_util.cc"
+ >
+ </File>
+ <File
RelativePath="..\base\tcp_client_socket_unittest.cc"
>
</File>
diff --git a/net/net.xcodeproj/project.pbxproj b/net/net.xcodeproj/project.pbxproj
index 11a8199..bb16121 100644
--- a/net/net.xcodeproj/project.pbxproj
+++ b/net/net.xcodeproj/project.pbxproj
@@ -151,6 +151,7 @@
8220FABD0E914ACA008170A9 /* ssl_client_socket_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32950E5A181C00A747DB /* ssl_client_socket_unittest.cc */; };
8220FAFC0E915561008170A9 /* ssl_client_socket_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32970E5A181C00A747DB /* ssl_client_socket_mac.cc */; };
825C2FCC0E5C968B00FDEAB7 /* ev_root_ca_metadata.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32BE0E5A181C00A747DB /* ev_root_ca_metadata.cc */; };
+ 826F15770EE48CEA00D973C7 /* ssl_test_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 826F15760EE48CEA00D973C7 /* ssl_test_util.cc */; };
827E139D0E81611D00183614 /* x509_certificate_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32800E5A181C00A747DB /* x509_certificate_mac.cc */; };
82ECB3090E5B651D00A913E3 /* mime_sniffer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32AD0E5A181C00A747DB /* mime_sniffer.cc */; };
93D11DCE0E91463000C36437 /* file_stream_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 93D11DCD0E91463000C36437 /* file_stream_posix.cc */; };
@@ -673,6 +674,8 @@
82113A270E84360200E3848F /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = "<group>"; };
82113BBC0E892E5800E3848F /* x509_certificate.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = x509_certificate.cc; sourceTree = "<group>"; };
8249C4920EA786B100A4A54B /* ssl_client_socket_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ssl_client_socket_mac.h; sourceTree = "<group>"; };
+ 826F15750EE48CEA00D973C7 /* ssl_test_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ssl_test_util.h; sourceTree = "<group>"; };
+ 826F15760EE48CEA00D973C7 /* ssl_test_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ssl_test_util.cc; sourceTree = "<group>"; };
936882DC0E9154E200043405 /* file_stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file_stream.h; sourceTree = "<group>"; };
93D11DCD0E91463000C36437 /* file_stream_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_stream_posix.cc; sourceTree = "<group>"; };
A5AB7BFB0EB7DBA10070A7D3 /* file_stream_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_stream_unittest.cc; sourceTree = "<group>"; };
@@ -967,6 +970,8 @@
7BED32930E5A181C00A747DB /* ssl_config_service.h */,
7BED32920E5A181C00A747DB /* ssl_config_service_unittest.cc */,
7BED32910E5A181C00A747DB /* ssl_info.h */,
+ 826F15760EE48CEA00D973C7 /* ssl_test_util.cc */,
+ 826F15750EE48CEA00D973C7 /* ssl_test_util.h */,
7BED328F0E5A181C00A747DB /* tcp_client_socket.h */,
E47E933E0E8924DC00CA613E /* tcp_client_socket_libevent.cc */,
7BED328E0E5A181C00A747DB /* tcp_client_socket_unittest.cc */,
@@ -1548,8 +1553,10 @@
7BD8F70E0E65DCE500034DE9 /* disk_cache_test_util.cc in Sources */,
7BD8F70F0E65DCEB00034DE9 /* entry_unittest.cc in Sources */,
7B4DF6B10E5B98ED004D7619 /* escape_unittest.cc in Sources */,
+ A5AB7BFC0EB7DBA10070A7D3 /* file_stream_unittest.cc in Sources */,
7BA0151F0E5A1B9200044150 /* gzip_filter_unittest.cc in Sources */,
7B82FF460E763620008F45CF /* host_resolver_unittest.cc in Sources */,
+ 042A4D480EC4F4500083281F /* http_auth_cache_unittest.cc in Sources */,
04C626D80E8DE3AA0067E92A /* http_auth_handler_basic_unittest.cc in Sources */,
04C626D60E8DE39E0067E92A /* http_auth_handler_digest_unittest.cc in Sources */,
04C626DA0E8DE3BA0067E92A /* http_auth_unittest.cc in Sources */,
@@ -1559,6 +1566,7 @@
821F21320E5CD756003C7E38 /* http_response_headers_unittest.cc in Sources */,
E4CE9C2E0E8C02ED00D5378C /* http_transaction_unittest.cc in Sources */,
821F21130E5CD662003C7E38 /* http_vary_data_unittest.cc in Sources */,
+ A50055C00EBF7CD6007B0A90 /* listen_socket_unittest.cc in Sources */,
7BD8F7100E65DCF000034DE9 /* mapped_file_unittest.cc in Sources */,
7B4DF9AC0E5C906A004D7619 /* mime_sniffer_unittest.cc in Sources */,
048268090E5B3B4800A30786 /* mime_util_unittest.cc in Sources */,
@@ -1568,15 +1576,13 @@
E4AFA6430E5241B400201347 /* run_all_unittests.cc in Sources */,
7BA362B70E8C3D040023C8B9 /* sdch_filter_unittest.cc in Sources */,
8220FABD0E914ACA008170A9 /* ssl_client_socket_unittest.cc in Sources */,
+ 826F15770EE48CEA00D973C7 /* ssl_test_util.cc in Sources */,
7BD8F7110E65DCF500034DE9 /* storage_block_unittest.cc in Sources */,
E47E93430E8924EE00CA613E /* tcp_client_socket_unittest.cc in Sources */,
- 7BA361450E8C341F0023C8B9 /* test_completion_callback_unittest.cc in Sources */,
- 82113A1D0E8434EE00E3848F /* x509_certificate_unittest.cc in Sources */,
- A5AB7BFC0EB7DBA10070A7D3 /* file_stream_unittest.cc in Sources */,
A50055BF0EBF7CB2007B0A90 /* telnet_server_unittest.cc in Sources */,
- A50055C00EBF7CD6007B0A90 /* listen_socket_unittest.cc in Sources */,
- 042A4D480EC4F4500083281F /* http_auth_cache_unittest.cc in Sources */,
+ 7BA361450E8C341F0023C8B9 /* test_completion_callback_unittest.cc in Sources */,
048133550ED27FEF005C5BBC /* url_request_unittest.cc in Sources */,
+ 82113A1D0E8434EE00E3848F /* x509_certificate_unittest.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
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 e2197f8..e94858d 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>
@@ -17,10 +21,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,42 @@ 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().ToWStringHack());
+
+ EXPECT_TRUE(util_.CheckCATrusted());
+ 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;
{