diff options
author | mef@chromium.org <mef@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-10 19:29:37 +0000 |
---|---|---|
committer | mef@chromium.org <mef@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-10 19:29:37 +0000 |
commit | ef9931028d0de995df987845d03e080a899ba826 (patch) | |
tree | 7b5a34887eb5c1648df1fefac17ebdbc33a146b0 /net | |
parent | 689941c25692361e84d0c07186d1361f5be54166 (diff) | |
download | chromium_src-ef9931028d0de995df987845d03e080a899ba826.zip chromium_src-ef9931028d0de995df987845d03e080a899ba826.tar.gz chromium_src-ef9931028d0de995df987845d03e080a899ba826.tar.bz2 |
Enable SDCH support over HTTPS if --enable-sdch=2 switch is present.
BUG=313716
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=243957
Review URL: https://codereview.chromium.org/123383002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244217 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/sdch_filter_unittest.cc | 77 | ||||
-rw-r--r-- | net/base/sdch_manager.cc | 35 | ||||
-rw-r--r-- | net/base/sdch_manager.h | 9 |
3 files changed, 114 insertions, 7 deletions
diff --git a/net/base/sdch_filter_unittest.cc b/net/base/sdch_filter_unittest.cc index 1cc70cb..ca73923 100644 --- a/net/base/sdch_filter_unittest.cc +++ b/net/base/sdch_filter_unittest.cc @@ -1232,6 +1232,83 @@ TEST_F(SdchFilterTest, CanSetExactMatchDictionary) { GURL("http://" + dictionary_domain))); } +TEST_F(SdchFilterTest, CanAdvertiseDictionaryOverHTTP) { + std::string dictionary_domain("x.y.z.google.com"); + std::string dictionary_text(NewSdchDictionary(dictionary_domain)); + + EXPECT_TRUE(sdch_manager_->AddSdchDictionary(dictionary_text, + GURL("http://" + dictionary_domain))); + + std::string dictionary_list; + // HTTP target URL can advertise dictionary. + sdch_manager_->GetAvailDictionaryList( + GURL("http://" + dictionary_domain + "/test"), + &dictionary_list); + EXPECT_FALSE(dictionary_list.empty()); +} + +TEST_F(SdchFilterTest, CanNotAdvertiseDictionaryOverHTTPS) { + std::string dictionary_domain("x.y.z.google.com"); + std::string dictionary_text(NewSdchDictionary(dictionary_domain)); + + EXPECT_TRUE(sdch_manager_->AddSdchDictionary(dictionary_text, + GURL("http://" + dictionary_domain))); + + std::string dictionary_list; + // HTTPS target URL should NOT advertise dictionary. + sdch_manager_->GetAvailDictionaryList( + GURL("https://" + dictionary_domain + "/test"), + &dictionary_list); + EXPECT_TRUE(dictionary_list.empty()); +} + +TEST_F(SdchFilterTest, CanUseHTTPSDictionaryOverHTTPSIfEnabled) { + std::string dictionary_domain("x.y.z.google.com"); + std::string dictionary_text(NewSdchDictionary(dictionary_domain)); + + EXPECT_TRUE(sdch_manager_->AddSdchDictionary(dictionary_text, + GURL("https://" + dictionary_domain))); + + GURL target_url("https://" + dictionary_domain + "/test"); + std::string dictionary_list; + // HTTPS target URL should advertise dictionary if secure scheme support is + // enabled. + sdch_manager_->EnableSecureSchemeSupport(true); + sdch_manager_->GetAvailDictionaryList(target_url, &dictionary_list); + EXPECT_FALSE(dictionary_list.empty()); + + // Dictionary should be available. + SdchManager::Dictionary* dictionary = NULL; + std::string client_hash; + std::string server_hash; + sdch_manager_->GenerateHash(dictionary_text, &client_hash, &server_hash); + sdch_manager_->GetVcdiffDictionary(server_hash, target_url, &dictionary); + EXPECT_TRUE(dictionary != NULL); +} + +TEST_F(SdchFilterTest, CanNotUseHTTPDictionaryOverHTTPS) { + std::string dictionary_domain("x.y.z.google.com"); + std::string dictionary_text(NewSdchDictionary(dictionary_domain)); + + EXPECT_TRUE(sdch_manager_->AddSdchDictionary(dictionary_text, + GURL("http://" + dictionary_domain))); + + GURL target_url("https://" + dictionary_domain + "/test"); + std::string dictionary_list; + // HTTPS target URL should not advertise dictionary acquired over HTTP even if + // secure scheme support is enabled. + sdch_manager_->EnableSecureSchemeSupport(true); + sdch_manager_->GetAvailDictionaryList(target_url, &dictionary_list); + EXPECT_TRUE(dictionary_list.empty()); + + SdchManager::Dictionary* dictionary = NULL; + std::string client_hash; + std::string server_hash; + sdch_manager_->GenerateHash(dictionary_text, &client_hash, &server_hash); + sdch_manager_->GetVcdiffDictionary(server_hash, target_url, &dictionary); + EXPECT_TRUE(dictionary == NULL); +} + TEST_F(SdchFilterTest, FailToSetDomainMismatchDictionary) { std::string dictionary_domain("x.y.z.google.com"); std::string dictionary_text(NewSdchDictionary(dictionary_domain)); diff --git a/net/base/sdch_manager.cc b/net/base/sdch_manager.cc index 17883b1..943fdd0 100644 --- a/net/base/sdch_manager.cc +++ b/net/base/sdch_manager.cc @@ -28,6 +28,9 @@ SdchManager* SdchManager::global_ = NULL; // static bool SdchManager::g_sdch_enabled_ = true; +// static +bool SdchManager::g_secure_scheme_supported_ = false; + //------------------------------------------------------------------------------ SdchManager::Dictionary::Dictionary(const std::string& dictionary_text, size_t offset, @@ -63,6 +66,8 @@ bool SdchManager::Dictionary::CanAdvertise(const GURL& target_url) { ports listed in the Port attribute. 3. The request URI path-matches the path header of the dictionary. 4. The request is not an HTTPS request. + We can override (ignore) item (4) only when we have explicitly enabled + HTTPS support AND dictionary has been acquired over HTTPS. */ if (!DomainMatch(target_url, domain_)) return false; @@ -70,7 +75,9 @@ bool SdchManager::Dictionary::CanAdvertise(const GURL& target_url) { return false; if (path_.size() && !PathMatch(target_url.path(), path_)) return false; - if (target_url.SchemeIsSecure()) + if (!SdchManager::secure_scheme_supported() && target_url.SchemeIsSecure()) + return false; + if (target_url.SchemeIsSecure() && !url_.SchemeIsSecure()) return false; if (base::Time::Now() > expiration_) return false; @@ -152,6 +159,8 @@ bool SdchManager::Dictionary::CanUse(const GURL& referring_url) { ports listed in the Port attribute. 3. The request URL path-matches the path attribute of the dictionary. 4. The request is not an HTTPS request. + We can override (ignore) item (4) only when we have explicitly enabled + HTTPS support AND dictionary has been acquired over HTTPS. */ if (!DomainMatch(referring_url, domain_)) { SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_DOMAIN); @@ -166,14 +175,19 @@ bool SdchManager::Dictionary::CanUse(const GURL& referring_url) { SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_PATH); return false; } - if (referring_url.SchemeIsSecure()) { + if (!SdchManager::secure_scheme_supported() && + referring_url.SchemeIsSecure()) { + SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_SCHEME); + return false; + } + if (referring_url.SchemeIsSecure() && !url_.SchemeIsSecure()) { SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_SCHEME); return false; } // TODO(jar): Remove overly restrictive failsafe test (added per security // review) when we have a need to be more general. - if (!referring_url.SchemeIs("http")) { + if (!referring_url.SchemeIsHTTPOrHTTPS()) { SdchErrorRecovery(ATTEMPT_TO_DECODE_NON_HTTP_DATA); return false; } @@ -252,6 +266,11 @@ void SdchManager::EnableSdchSupport(bool enabled) { } // static +void SdchManager::EnableSecureSchemeSupport(bool enabled) { + g_secure_scheme_supported_ = enabled; +} + +// static void SdchManager::BlacklistDomain(const GURL& url) { if (!global_ ) return; @@ -344,7 +363,8 @@ bool SdchManager::CanFetchDictionary(const GURL& referring_url, DCHECK(CalledOnValidThread()); /* The user agent may retrieve a dictionary from the dictionary URL if all of the following are true: - 1 The dictionary URL host name matches the referrer URL host name + 1 The dictionary URL host name matches the referrer URL host name and + scheme. 2 The dictionary URL host name domain matches the parent domain of the referrer URL host name 3 The parent domain of the referrer URL host name is not a top level @@ -353,18 +373,19 @@ bool SdchManager::CanFetchDictionary(const GURL& referring_url, */ // Item (1) above implies item (2). Spec should be updated. // I take "host name match" to be "is identical to" - if (referring_url.host() != dictionary_url.host()) { + if (referring_url.host() != dictionary_url.host() || + referring_url.scheme() != dictionary_url.scheme()) { SdchErrorRecovery(DICTIONARY_LOAD_ATTEMPT_FROM_DIFFERENT_HOST); return false; } - if (referring_url.SchemeIs("https")) { + if (!secure_scheme_supported() && referring_url.SchemeIsSecure()) { SdchErrorRecovery(DICTIONARY_SELECTED_FOR_SSL); return false; } // TODO(jar): Remove this failsafe conservative hack which is more restrictive // than current SDCH spec when needed, and justified by security audit. - if (!referring_url.SchemeIs("http")) { + if (!referring_url.SchemeIsHTTPOrHTTPS()) { SdchErrorRecovery(DICTIONARY_SELECTED_FROM_NON_HTTP); return false; } diff --git a/net/base/sdch_manager.h b/net/base/sdch_manager.h index 4f45966..a5dd21f 100644 --- a/net/base/sdch_manager.h +++ b/net/base/sdch_manager.h @@ -251,6 +251,11 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) { static bool sdch_enabled() { return g_sdch_enabled_; } + // Enables or disables SDCH compression over secure connection. + static void EnableSecureSchemeSupport(bool enabled); + + static bool secure_scheme_supported() { return g_secure_scheme_supported_; } + // Briefly prevent further advertising of SDCH on this domain (if SDCH is // enabled). After enough calls to IsInSupportedDomain() the blacklisting // will be removed. Additional blacklists take exponentially more calls @@ -344,6 +349,10 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) { // Support SDCH compression, by advertising in headers. static bool g_sdch_enabled_; + // Support SDCH compression for HTTPS requests and responses. When supported, + // HTTPS applicable dictionaries MUST have been acquired securely via HTTPS. + static bool g_secure_scheme_supported_; + // A simple implementation of a RFC 3548 "URL safe" base64 encoder. static void UrlSafeBase64Encode(const std::string& input, std::string* output); |