Commit b272d3c9 authored by Matt Mueller's avatar Matt Mueller Committed by Commit Bot

Add more browser_tests for client auth: failed signing and continue without cert

Bug: 887095
Change-Id: I5556c05c6d8444ffb0a6ebec2ef46396e857fed4
Reviewed-on: https://chromium-review.googlesource.com/c/1286862
Commit-Queue: Matt Mueller <mattm@chromium.org>
Reviewed-by: default avatarRyan Sleevi <rsleevi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601804}
parent 72c35d8c
...@@ -2500,6 +2500,30 @@ std::unique_ptr<net::ClientCertStore> CreateCertStore() { ...@@ -2500,6 +2500,30 @@ std::unique_ptr<net::ClientCertStore> CreateCertStore() {
new ClientCertStoreStub(std::move(cert_identity_list))); new ClientCertStoreStub(std::move(cert_identity_list)));
} }
std::unique_ptr<net::ClientCertStore> CreateFailSigningCertStore() {
base::FilePath certs_dir = net::GetTestCertsDirectory();
net::ClientCertIdentityList cert_identity_list;
{
base::ScopedAllowBlockingForTesting allow_blocking;
std::unique_ptr<net::FakeClientCertIdentity> cert_identity =
net::FakeClientCertIdentity::CreateFromCertAndFailSigning(
certs_dir, "client_1.pem");
EXPECT_TRUE(cert_identity.get());
if (cert_identity)
cert_identity_list.push_back(std::move(cert_identity));
}
return std::unique_ptr<net::ClientCertStore>(
new ClientCertStoreStub(std::move(cert_identity_list)));
}
std::unique_ptr<net::ClientCertStore> CreateEmptyCertStore() {
return std::unique_ptr<net::ClientCertStore>(new ClientCertStoreStub({}));
}
IN_PROC_BROWSER_TEST_P(SSLUITest, TestBrowserUseClientCertStore) { IN_PROC_BROWSER_TEST_P(SSLUITest, TestBrowserUseClientCertStore) {
// Make the browser use the ClientCertStoreStub instead of the regular one. // Make the browser use the ClientCertStoreStub instead of the regular one.
ProfileIOData::FromResourceContext(browser()->profile()->GetResourceContext()) ProfileIOData::FromResourceContext(browser()->profile()->GetResourceContext())
...@@ -2535,6 +2559,69 @@ IN_PROC_BROWSER_TEST_P(SSLUITest, TestBrowserUseClientCertStore) { ...@@ -2535,6 +2559,69 @@ IN_PROC_BROWSER_TEST_P(SSLUITest, TestBrowserUseClientCertStore) {
EXPECT_EQ("pass", tab->GetLastCommittedURL().ref()); EXPECT_EQ("pass", tab->GetLastCommittedURL().ref());
} }
IN_PROC_BROWSER_TEST_P(SSLUITest, TestClientAuthSigningFails) {
// Make the browser use the ClientCertStoreStub instead of the regular one.
ProfileIOData::FromResourceContext(browser()->profile()->GetResourceContext())
->set_client_cert_store_factory_for_testing(
base::BindRepeating(&CreateFailSigningCertStore));
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
net::SSLServerConfig ssl_config;
ssl_config.client_cert_type =
net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
https_server.ServeFilesFromSourceDirectory("chrome/test/data");
ASSERT_TRUE(https_server.Start());
GURL https_url =
https_server.GetURL("/ssl/browser_use_client_cert_store.html");
// Add an entry into AutoSelectCertificateForUrls policy for automatic client
// cert selection.
WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
DCHECK(profile);
std::unique_ptr<base::DictionaryValue> setting =
std::make_unique<base::DictionaryValue>();
base::Value* filters = setting->SetKey("filters", base::ListValue());
filters->GetList().push_back(base::DictionaryValue());
HostContentSettingsMapFactory::GetForProfile(profile)
->SetWebsiteSettingDefaultScope(
https_url, GURL(), CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
std::string(), std::move(setting));
// Visit a HTTPS page which requires client certs.
ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(),
https_url, 1);
// Page should not load successfully.
EXPECT_EQ("", tab->GetLastCommittedURL().ref());
}
IN_PROC_BROWSER_TEST_P(SSLUITest, TestClientAuthContinueWithoutCert) {
// Make the browser use a ClientCertStoreStub that returns no certs.
ProfileIOData::FromResourceContext(browser()->profile()->GetResourceContext())
->set_client_cert_store_factory_for_testing(
base::BindRepeating(&CreateEmptyCertStore));
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
net::SSLServerConfig ssl_config;
ssl_config.client_cert_type =
net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
https_server.ServeFilesFromSourceDirectory("chrome/test/data");
ASSERT_TRUE(https_server.Start());
GURL https_url =
https_server.GetURL("/ssl/browser_use_client_cert_store.html");
// Visit a HTTPS page which requires client certs.
// The browser should automatically continue to the site without a client
// cert, since the ClientCertStore returns no certs.
ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(),
https_url, 1);
WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
// Page should not load successfully.
EXPECT_EQ("", tab->GetLastCommittedURL().ref());
}
// Open a page with a HTTPS error in a tab with no prior navigation (through a // Open a page with a HTTPS error in a tab with no prior navigation (through a
// link with a blank target). This is to test that the lack of navigation entry // link with a blank target). This is to test that the lack of navigation entry
// does not cause any problems (it was causing a crasher, see // does not cause any problems (it was causing a crasher, see
......
...@@ -52,6 +52,20 @@ FakeClientCertIdentity::CreateFromCertAndKeyFiles( ...@@ -52,6 +52,20 @@ FakeClientCertIdentity::CreateFromCertAndKeyFiles(
return std::make_unique<FakeClientCertIdentity>(cert, ssl_private_key); return std::make_unique<FakeClientCertIdentity>(cert, ssl_private_key);
} }
// static
std::unique_ptr<FakeClientCertIdentity>
FakeClientCertIdentity::CreateFromCertAndFailSigning(
const base::FilePath& dir,
const std::string& cert_filename) {
scoped_refptr<X509Certificate> cert =
net::ImportCertFromFile(dir, cert_filename);
if (!cert)
return nullptr;
return std::make_unique<FakeClientCertIdentity>(
cert, CreateFailSigningSSLPrivateKey());
}
std::unique_ptr<FakeClientCertIdentity> FakeClientCertIdentity::Copy() { std::unique_ptr<FakeClientCertIdentity> FakeClientCertIdentity::Copy() {
return std::make_unique<FakeClientCertIdentity>(certificate(), key_); return std::make_unique<FakeClientCertIdentity>(certificate(), key_);
} }
......
...@@ -29,6 +29,12 @@ class FakeClientCertIdentity : public ClientCertIdentity { ...@@ -29,6 +29,12 @@ class FakeClientCertIdentity : public ClientCertIdentity {
const std::string& cert_filename, const std::string& cert_filename,
const std::string& key_filename); const std::string& key_filename);
// Creates a FakeClientCertIdentity from a certificate file (DER or PEM).
// Signing attempts will fail. Returns nullptr on error.
static std::unique_ptr<FakeClientCertIdentity> CreateFromCertAndFailSigning(
const base::FilePath& dir,
const std::string& cert_filename);
// Duplicates the FakeClientCertIdentity. // Duplicates the FakeClientCertIdentity.
std::unique_ptr<FakeClientCertIdentity> Copy(); std::unique_ptr<FakeClientCertIdentity> Copy();
......
...@@ -70,6 +70,26 @@ class TestSSLPlatformKey : public ThreadedSSLPrivateKey::Delegate { ...@@ -70,6 +70,26 @@ class TestSSLPlatformKey : public ThreadedSSLPrivateKey::Delegate {
DISALLOW_COPY_AND_ASSIGN(TestSSLPlatformKey); DISALLOW_COPY_AND_ASSIGN(TestSSLPlatformKey);
}; };
class FailingSSLPlatformKey : public ThreadedSSLPrivateKey::Delegate {
public:
FailingSSLPlatformKey() = default;
~FailingSSLPlatformKey() override = default;
std::vector<uint16_t> GetAlgorithmPreferences() override {
return SSLPrivateKey::DefaultAlgorithmPreferences(EVP_PKEY_RSA,
true /* supports PSS */);
}
Error Sign(uint16_t algorithm,
base::span<const uint8_t> input,
std::vector<uint8_t>* signature) override {
return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
}
private:
DISALLOW_COPY_AND_ASSIGN(FailingSSLPlatformKey);
};
} // namespace } // namespace
scoped_refptr<SSLPrivateKey> WrapOpenSSLPrivateKey( scoped_refptr<SSLPrivateKey> WrapOpenSSLPrivateKey(
...@@ -87,4 +107,9 @@ scoped_refptr<SSLPrivateKey> WrapRSAPrivateKey( ...@@ -87,4 +107,9 @@ scoped_refptr<SSLPrivateKey> WrapRSAPrivateKey(
return net::WrapOpenSSLPrivateKey(bssl::UpRef(rsa_private_key->key())); return net::WrapOpenSSLPrivateKey(bssl::UpRef(rsa_private_key->key()));
} }
scoped_refptr<SSLPrivateKey> CreateFailSigningSSLPrivateKey() {
return base::MakeRefCounted<ThreadedSSLPrivateKey>(
std::make_unique<FailingSSLPlatformKey>(), GetSSLPlatformKeyTaskRunner());
}
} // namespace net } // namespace net
...@@ -23,6 +23,7 @@ NET_EXPORT scoped_refptr<SSLPrivateKey> WrapOpenSSLPrivateKey( ...@@ -23,6 +23,7 @@ NET_EXPORT scoped_refptr<SSLPrivateKey> WrapOpenSSLPrivateKey(
bssl::UniquePtr<EVP_PKEY> key); bssl::UniquePtr<EVP_PKEY> key);
NET_EXPORT scoped_refptr<SSLPrivateKey> WrapRSAPrivateKey( NET_EXPORT scoped_refptr<SSLPrivateKey> WrapRSAPrivateKey(
crypto::RSAPrivateKey* rsa_private_key); crypto::RSAPrivateKey* rsa_private_key);
NET_EXPORT scoped_refptr<SSLPrivateKey> CreateFailSigningSSLPrivateKey();
} // namespace net } // namespace net
......
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