Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2543)

Unified Diff: net/http/http_network_transaction_unittest.cc

Issue 1074193003: Verify alternative server certificate validity for origin. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nit. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/base/net_error_list.h ('k') | net/http/http_stream_factory_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/http_network_transaction_unittest.cc
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 1c677dbb84bb54dca78cc5feea30af7c6cf82435..36b1e51720dfe378b3ea021314bbb7d68755caba 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -18,6 +18,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_file_util.h"
@@ -11867,6 +11868,162 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
}
+class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
+ public:
+ void Run(bool pooling, bool valid) {
+ HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
+ 443);
+ HostPortPair alternative("www.example.org", 443);
+
+ base::FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<X509Certificate> cert(
+ ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
+ ASSERT_TRUE(cert.get());
+ bool common_name_fallback_used;
+ EXPECT_EQ(valid,
+ cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
+ EXPECT_TRUE(
+ cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ ssl.SetNextProto(GetParam());
+ ssl.cert = cert;
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ // If pooling, then start a request to alternative first to create a
+ // SpdySession.
+ std::string url0 = "https://www.example.org:443";
+ // Second request to origin, which has an alternative service, and could
+ // open a connection to the alternative host or pool to the existing one.
+ std::string url1("https://");
+ url1.append(origin.host());
+ url1.append(":443");
+
+ scoped_ptr<SpdyFrame> req0;
+ scoped_ptr<SpdyFrame> req1;
+ scoped_ptr<SpdyFrame> resp0;
+ scoped_ptr<SpdyFrame> body0;
+ scoped_ptr<SpdyFrame> resp1;
+ scoped_ptr<SpdyFrame> body1;
+ std::vector<MockWrite> writes;
+ std::vector<MockRead> reads;
+
+ if (pooling) {
+ req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
+ req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
+
+ writes.push_back(CreateMockWrite(*req0, 0));
+ writes.push_back(CreateMockWrite(*req1, 3));
+
+ resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+ body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
+ resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+ body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
+
+ reads.push_back(CreateMockRead(*resp0, 1));
+ reads.push_back(CreateMockRead(*body0, 2));
+ reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
+ reads.push_back(CreateMockRead(*resp1, 5));
+ reads.push_back(CreateMockRead(*body1, 6));
+ reads.push_back(MockRead(ASYNC, OK, 7));
+ } else {
+ req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
+
+ writes.push_back(CreateMockWrite(*req1, 0));
+
+ resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+ body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
+
+ reads.push_back(CreateMockRead(*resp1, 1));
+ reads.push_back(CreateMockRead(*body1, 2));
+ reads.push_back(MockRead(ASYNC, OK, 3));
+ }
+
+ OrderedSocketData data(vector_as_array(&reads), reads.size(),
+ vector_as_array(&writes), writes.size());
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ // Connection to the origin fails.
+ MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
+ StaticSocketDataProvider data_refused;
+ data_refused.set_connect_data(mock_connect);
+ session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
+
+ session_deps_.use_alternate_protocols = true;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ base::WeakPtr<HttpServerProperties> http_server_properties =
+ session->http_server_properties();
+ AlternativeService alternative_service(
+ AlternateProtocolFromNextProto(GetParam()), alternative);
+ http_server_properties->SetAlternativeService(origin, alternative_service,
+ 1.0);
+
+ // First request to alternative.
+ if (pooling) {
+ scoped_ptr<HttpTransaction> trans0(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ HttpRequestInfo request0;
+ request0.method = "GET";
+ request0.url = GURL(url0);
+ request0.load_flags = 0;
+ TestCompletionCallback callback0;
+
+ int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ rv = callback0.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ }
+
+ // Second request to origin.
+ scoped_ptr<HttpTransaction> trans1(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ HttpRequestInfo request1;
+ request1.method = "GET";
+ request1.url = GURL(url1);
+ request1.load_flags = 0;
+ TestCompletionCallback callback1;
+
+ int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ rv = callback1.WaitForResult();
+ if (valid) {
+ EXPECT_EQ(OK, rv);
+ } else {
+ if (pooling) {
+ EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
+ } else {
+ EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
+ }
+ }
+ }
+};
+
+INSTANTIATE_TEST_CASE_P(NextProto,
+ AltSvcCertificateVerificationTest,
+ testing::Values(kProtoSPDY31,
+ kProtoSPDY4_14,
+ kProtoSPDY4));
+
+// The alternative service host must exhibit a certificate that is valid for the
+// origin host. Test that this is enforced when pooling to an existing
+// connection.
+TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
+ Run(true, true);
+}
+
+TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
+ Run(true, false);
+}
+
+// The alternative service host must exhibit a certificate that is valid for the
+// origin host. Test that this is enforced when opening a new connection.
+TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
+ Run(false, true);
+}
+
+TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
+ Run(false, false);
+}
+
TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
const std::string https_url = "https://www.example.org:8080/";
const std::string http_url = "http://www.example.org:8080/";
« no previous file with comments | « net/base/net_error_list.h ('k') | net/http/http_stream_factory_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698