Commit 72b2686a authored by toyoshim@chromium.org's avatar toyoshim@chromium.org

- add client cert authentication support in test websocket server

- add new browser test which access to a page which requires client cert

BUG=136950
TEST=browser_tests

Review URL: https://chromiumcodereview.appspot.com/10541168

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146294 0039d316-1c4b-4281-b951-d872f2087c98
parent 7feb9617
......@@ -9,6 +9,8 @@
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_navigator.h"
......@@ -31,7 +33,10 @@
#include "content/public/common/security_style.h"
#include "content/public/common/ssl_status.h"
#include "content/public/test/test_renderer_host.h"
#include "net/base/cert_database.h"
#include "net/base/cert_status_flags.h"
#include "net/base/crypto_module.h"
#include "net/base/net_errors.h"
#include "net/test/test_server.h"
using content::InterstitialPage;
......@@ -599,6 +604,70 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestWSSInvalidCertAndGoForward) {
EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass"));
}
#if defined(USE_NSS)
// Visit a HTTPS page which requires client cert authentication. The client
// cert will be selected automatically, then a test which uses WebSocket runs.
IN_PROC_BROWSER_TEST_F(SSLUITest, TestWSSClientCert) {
// Import client cert for test. These interfaces require NSS.
net::CertDatabase cert_db;
scoped_refptr<net::CryptoModule> crypt_module = cert_db.GetPublicModule();
std::string pkcs12_data;
FilePath cert_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &cert_path));
cert_path = cert_path.Append(FILE_PATH_LITERAL("ssl"));
cert_path = cert_path.Append(FILE_PATH_LITERAL("client_cert.p12"));
EXPECT_TRUE(file_util::ReadFileToString(cert_path, &pkcs12_data));
EXPECT_EQ(net::OK, cert_db.ImportFromPKCS12(crypt_module,
pkcs12_data,
string16(),
true,
NULL));
// Start pywebsocket with TLS and client cert authentication.
ui_test_utils::TestWebSocketServer wss_server;
int port = wss_server.UseRandomPort();
wss_server.UseTLS();
wss_server.UseClientAuthentication();
FilePath wss_root_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &wss_root_dir));
ASSERT_TRUE(wss_server.Start(wss_root_dir));
std::string urlPath =
StringPrintf("%s%d%s", "https://localhost:", port, "/wss.html");
GURL url(urlPath);
// Setup page title observer.
WebContents* tab = chrome::GetActiveWebContents(browser());
ui_test_utils::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
// Add an entry into AutoSelectCertificateForUrls policy for automatic client
// cert selection.
Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
DCHECK(profile);
scoped_ptr<DictionaryValue> dict(new DictionaryValue());
dict->SetString("ISSUER.CN", "pywebsocket");
profile->GetHostContentSettingsMap()->SetWebsiteSetting(
ContentSettingsPattern::FromURL(url),
ContentSettingsPattern::FromURL(url),
CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
std::string(),
dict.release());
// Visit a HTTPS page which requires client certs.
ui_test_utils::NavigateToURL(browser(), url);
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
false, true); // Interstitial showing
// Proceed anyway.
ProceedThroughInterstitial(tab);
// Test page runs a WebSocket wss connection test. The result will be shown
// as page title.
const string16 result = watcher.WaitAndGetTitle();
EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass"));
}
#endif // defined(USE_NSS)
// Flaky on CrOS http://crbug.com/92292
#if defined(OS_CHROMEOS)
#define MAYBE_TestHTTPSErrorWithNoNavEntry \
......
......@@ -877,7 +877,8 @@ void MessageLoopRunner::Quit() {
TestWebSocketServer::TestWebSocketServer()
: started_(false),
port_(kDefaultWsPort),
secure_(false) {
secure_(false),
client_authentication_(false) {
#if defined(OS_POSIX)
process_group_id_ = base::kNullProcessHandle;
#endif
......@@ -892,6 +893,10 @@ void TestWebSocketServer::UseTLS() {
secure_ = true;
}
void TestWebSocketServer::UseClientAuthentication() {
client_authentication_ = true;
}
bool TestWebSocketServer::Start(const FilePath& root_directory) {
if (started_)
return true;
......@@ -909,6 +914,13 @@ bool TestWebSocketServer::Start(const FilePath& root_directory) {
LOG(ERROR) << "Unable to create a temporary directory.";
return false;
}
if (client_authentication_) {
FilePath cacert_path(root_directory);
cmd_line->AppendArg("--ca-certificate");
cacert_path = cacert_path.Append(FILE_PATH_LITERAL("ssl"));
cacert_path = cacert_path.Append(FILE_PATH_LITERAL("cacert.pem"));
cmd_line->AppendArgNative(cacert_path.value());
}
cmd_line->AppendArgNative(FILE_PATH_LITERAL("--output-dir=") +
temp_dir_.path().value());
websocket_pid_file_ = temp_dir_.path().AppendASCII("websocket.pid");
......
......@@ -359,6 +359,9 @@ class TestWebSocketServer {
// Serves with TLS.
void UseTLS();
// Requests client cert authentication.
void UseClientAuthentication();
// Starts the python websocket server using |root_directory|. Returns whether
// the server was successfully started.
bool Start(const FilePath& root_directory);
......@@ -397,6 +400,9 @@ class TestWebSocketServer {
// If the python websocket server serves with TLS.
bool secure_;
// If the python websocket server requests client cert authentication.
bool client_authentication_;
DISALLOW_COPY_AND_ASSIGN(TestWebSocketServer);
};
......
-----BEGIN CERTIFICATE-----
MIICvDCCAiWgAwIBAgIJAKqVghkGF1rSMA0GCSqGSIb3DQEBBQUAMEkxCzAJBgNV
BAYTAkpQMQ4wDAYDVQQIEwVUb2t5bzEUMBIGA1UEChMLcHl3ZWJzb2NrZXQxFDAS
BgNVBAMTC3B5d2Vic29ja2V0MB4XDTEyMDYwNjA3MjQzM1oXDTM5MTAyMzA3MjQz
M1owSTELMAkGA1UEBhMCSlAxDjAMBgNVBAgTBVRva3lvMRQwEgYDVQQKEwtweXdl
YnNvY2tldDEUMBIGA1UEAxMLcHl3ZWJzb2NrZXQwgZ8wDQYJKoZIhvcNAQEBBQAD
gY0AMIGJAoGBAKoSEW2biQxVrMMKdn/8PJzDYiSXDPR9WQbLRRQ1Gm5jkCYiahXW
u2CbTThfPPfi2NHA3I+HlT7gO9yR7RVUvN6ISUzGwXDEq4f4UNqtQOhQaqqK+CZ9
LO/BhO/YYfNrbSPlYzHUKaT9ese7xO9VzVKLW+qUf2Mjh4/+SzxBDNP7AgMBAAGj
gaswgagwHQYDVR0OBBYEFOsWdxCSuyhwaZeab6BoTho3++bzMHkGA1UdIwRyMHCA
FOsWdxCSuyhwaZeab6BoTho3++bzoU2kSzBJMQswCQYDVQQGEwJKUDEOMAwGA1UE
CBMFVG9reW8xFDASBgNVBAoTC3B5d2Vic29ja2V0MRQwEgYDVQQDEwtweXdlYnNv
Y2tldIIJAKqVghkGF1rSMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEA
gsMI1WEYqNw/jhUIdrTBcCxJ0X6hJvA9ziKANVm1Rs+4P3YDArkQ8bCr6xY+Kw7s
Zp0yE7dM8GMdi+DU6hL3t3E5eMkTS1yZr9WCK4f2RLo+et98selZydpHemF3DJJ3
gAj8Sx4LBaG8Cb/WnEMPv3MxG3fBE5favF6V4jU07hQ=
-----END CERTIFICATE-----
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment