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

Side by Side 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, 7 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_network_transaction.h" 5 #include "net/http/http_network_transaction.h"
6 6
7 #include <math.h> // ceil 7 #include <math.h> // ceil
8 #include <stdarg.h> 8 #include <stdarg.h>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
16 #include "base/json/json_writer.h" 16 #include "base/json/json_writer.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_ptr.h"
19 #include "base/memory/weak_ptr.h" 19 #include "base/memory/weak_ptr.h"
20 #include "base/run_loop.h" 20 #include "base/run_loop.h"
21 #include "base/stl_util.h"
21 #include "base/strings/string_util.h" 22 #include "base/strings/string_util.h"
22 #include "base/strings/utf_string_conversions.h" 23 #include "base/strings/utf_string_conversions.h"
23 #include "base/test/test_file_util.h" 24 #include "base/test/test_file_util.h"
24 #include "net/base/auth.h" 25 #include "net/base/auth.h"
25 #include "net/base/chunked_upload_data_stream.h" 26 #include "net/base/chunked_upload_data_stream.h"
26 #include "net/base/completion_callback.h" 27 #include "net/base/completion_callback.h"
27 #include "net/base/elements_upload_data_stream.h" 28 #include "net/base/elements_upload_data_stream.h"
28 #include "net/base/load_timing_info.h" 29 #include "net/base/load_timing_info.h"
29 #include "net/base/load_timing_info_test_util.h" 30 #include "net/base/load_timing_info_test_util.h"
30 #include "net/base/net_errors.h" 31 #include "net/base/net_errors.h"
(...skipping 11829 matching lines...) Expand 10 before | Expand all | Expand 10 after
11860 HttpNetworkTransaction trans2(MEDIUM, session.get()); 11861 HttpNetworkTransaction trans2(MEDIUM, session.get());
11861 TestCompletionCallback callback2; 11862 TestCompletionCallback callback2;
11862 EXPECT_EQ(ERR_IO_PENDING, 11863 EXPECT_EQ(ERR_IO_PENDING,
11863 trans2.Start(&request2, callback2.callback(), BoundNetLog())); 11864 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
11864 base::MessageLoop::current()->RunUntilIdle(); 11865 base::MessageLoop::current()->RunUntilIdle();
11865 11866
11866 EXPECT_EQ(OK, callback2.WaitForResult()); 11867 EXPECT_EQ(OK, callback2.WaitForResult());
11867 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy); 11868 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11868 } 11869 }
11869 11870
11871 class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
11872 public:
11873 void Run(bool pooling, bool valid) {
11874 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
11875 443);
11876 HostPortPair alternative("www.example.org", 443);
11877
11878 base::FilePath certs_dir = GetTestCertsDirectory();
11879 scoped_refptr<X509Certificate> cert(
11880 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
11881 ASSERT_TRUE(cert.get());
11882 bool common_name_fallback_used;
11883 EXPECT_EQ(valid,
11884 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
11885 EXPECT_TRUE(
11886 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
11887 SSLSocketDataProvider ssl(ASYNC, OK);
11888 ssl.SetNextProto(GetParam());
11889 ssl.cert = cert;
11890 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11891
11892 // If pooling, then start a request to alternative first to create a
11893 // SpdySession.
11894 std::string url0 = "https://www.example.org:443";
11895 // Second request to origin, which has an alternative service, and could
11896 // open a connection to the alternative host or pool to the existing one.
11897 std::string url1("https://");
11898 url1.append(origin.host());
11899 url1.append(":443");
11900
11901 scoped_ptr<SpdyFrame> req0;
11902 scoped_ptr<SpdyFrame> req1;
11903 scoped_ptr<SpdyFrame> resp0;
11904 scoped_ptr<SpdyFrame> body0;
11905 scoped_ptr<SpdyFrame> resp1;
11906 scoped_ptr<SpdyFrame> body1;
11907 std::vector<MockWrite> writes;
11908 std::vector<MockRead> reads;
11909
11910 if (pooling) {
11911 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
11912 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
11913
11914 writes.push_back(CreateMockWrite(*req0, 0));
11915 writes.push_back(CreateMockWrite(*req1, 3));
11916
11917 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11918 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11919 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11920 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
11921
11922 reads.push_back(CreateMockRead(*resp0, 1));
11923 reads.push_back(CreateMockRead(*body0, 2));
11924 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
11925 reads.push_back(CreateMockRead(*resp1, 5));
11926 reads.push_back(CreateMockRead(*body1, 6));
11927 reads.push_back(MockRead(ASYNC, OK, 7));
11928 } else {
11929 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
11930
11931 writes.push_back(CreateMockWrite(*req1, 0));
11932
11933 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11934 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11935
11936 reads.push_back(CreateMockRead(*resp1, 1));
11937 reads.push_back(CreateMockRead(*body1, 2));
11938 reads.push_back(MockRead(ASYNC, OK, 3));
11939 }
11940
11941 OrderedSocketData data(vector_as_array(&reads), reads.size(),
11942 vector_as_array(&writes), writes.size());
11943 session_deps_.socket_factory->AddSocketDataProvider(&data);
11944
11945 // Connection to the origin fails.
11946 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11947 StaticSocketDataProvider data_refused;
11948 data_refused.set_connect_data(mock_connect);
11949 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11950
11951 session_deps_.use_alternate_protocols = true;
11952 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11953 base::WeakPtr<HttpServerProperties> http_server_properties =
11954 session->http_server_properties();
11955 AlternativeService alternative_service(
11956 AlternateProtocolFromNextProto(GetParam()), alternative);
11957 http_server_properties->SetAlternativeService(origin, alternative_service,
11958 1.0);
11959
11960 // First request to alternative.
11961 if (pooling) {
11962 scoped_ptr<HttpTransaction> trans0(
11963 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11964 HttpRequestInfo request0;
11965 request0.method = "GET";
11966 request0.url = GURL(url0);
11967 request0.load_flags = 0;
11968 TestCompletionCallback callback0;
11969
11970 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
11971 EXPECT_EQ(ERR_IO_PENDING, rv);
11972 rv = callback0.WaitForResult();
11973 EXPECT_EQ(OK, rv);
11974 }
11975
11976 // Second request to origin.
11977 scoped_ptr<HttpTransaction> trans1(
11978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11979 HttpRequestInfo request1;
11980 request1.method = "GET";
11981 request1.url = GURL(url1);
11982 request1.load_flags = 0;
11983 TestCompletionCallback callback1;
11984
11985 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
11986 EXPECT_EQ(ERR_IO_PENDING, rv);
11987 rv = callback1.WaitForResult();
11988 if (valid) {
11989 EXPECT_EQ(OK, rv);
11990 } else {
11991 if (pooling) {
11992 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11993 } else {
11994 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
11995 }
11996 }
11997 }
11998 };
11999
12000 INSTANTIATE_TEST_CASE_P(NextProto,
12001 AltSvcCertificateVerificationTest,
12002 testing::Values(kProtoSPDY31,
12003 kProtoSPDY4_14,
12004 kProtoSPDY4));
12005
12006 // The alternative service host must exhibit a certificate that is valid for the
12007 // origin host. Test that this is enforced when pooling to an existing
12008 // connection.
12009 TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
12010 Run(true, true);
12011 }
12012
12013 TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
12014 Run(true, false);
12015 }
12016
12017 // The alternative service host must exhibit a certificate that is valid for the
12018 // origin host. Test that this is enforced when opening a new connection.
12019 TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
12020 Run(false, true);
12021 }
12022
12023 TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
12024 Run(false, false);
12025 }
12026
11870 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { 12027 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
11871 const std::string https_url = "https://www.example.org:8080/"; 12028 const std::string https_url = "https://www.example.org:8080/";
11872 const std::string http_url = "http://www.example.org:8080/"; 12029 const std::string http_url = "http://www.example.org:8080/";
11873 12030
11874 // SPDY GET for HTTPS URL (through CONNECT tunnel) 12031 // SPDY GET for HTTPS URL (through CONNECT tunnel)
11875 const HostPortPair host_port_pair("www.example.org", 8080); 12032 const HostPortPair host_port_pair("www.example.org", 8080);
11876 scoped_ptr<SpdyFrame> connect( 12033 scoped_ptr<SpdyFrame> connect(
11877 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair)); 12034 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
11878 scoped_ptr<SpdyFrame> req1( 12035 scoped_ptr<SpdyFrame> req1(
11879 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 12036 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after
13889 ASSERT_TRUE(response); 14046 ASSERT_TRUE(response);
13890 ASSERT_TRUE(response->headers.get()); 14047 ASSERT_TRUE(response->headers.get());
13891 14048
13892 EXPECT_EQ(101, response->headers->response_code()); 14049 EXPECT_EQ(101, response->headers->response_code());
13893 14050
13894 trans.reset(); 14051 trans.reset();
13895 session->CloseAllConnections(); 14052 session->CloseAllConnections();
13896 } 14053 }
13897 14054
13898 } // namespace net 14055 } // namespace net
OLDNEW
« 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