Index: net/http/http_security_headers.cc |
diff --git a/net/http/http_security_headers.cc b/net/http/http_security_headers.cc |
index d95e5878d7c4ce10e2e393d875fb254257d5b6de..8924d9c67a9a992ee509539a67b52bca9e7817da 100644 |
--- a/net/http/http_security_headers.cc |
+++ b/net/http/http_security_headers.cc |
@@ -92,29 +92,6 @@ bool IsPinListValid(const HashValueVector& pins, |
HashesIntersect(pins, from_cert_chain); |
} |
-std::string Strip(const std::string& source) { |
- if (source.empty()) |
- return source; |
- |
- std::string::const_iterator start = source.begin(); |
- std::string::const_iterator end = source.end(); |
- HttpUtil::TrimLWS(&start, &end); |
- return std::string(start, end); |
-} |
- |
-typedef std::pair<std::string, std::string> StringPair; |
- |
-StringPair Split(const std::string& source, char delimiter) { |
- StringPair pair; |
- size_t point = source.find(delimiter); |
- |
- pair.first = source.substr(0, point); |
- if (std::string::npos != point) |
- pair.second = source.substr(point + 1); |
- |
- return pair; |
-} |
- |
bool ParseAndAppendPin(const std::string& value, |
HashValueTag tag, |
HashValueVector* hashes) { |
@@ -273,51 +250,70 @@ bool ParseHSTSHeader(const std::string& value, |
} |
} |
-// "Public-Key-Pins" ":" |
+// "Public-Key-Pins[-Report-Only]" ":" |
// "max-age" "=" delta-seconds ";" |
// "pin-" algo "=" base64 [ ";" ... ] |
+// [ ";" "includeSubdomains" ] |
+// [ ";" "report-uri" "=" uri-reference ] |
bool ParseHPKPHeader(const std::string& value, |
const HashValueVector& chain_hashes, |
base::TimeDelta* max_age, |
bool* include_subdomains, |
- HashValueVector* hashes) { |
+ HashValueVector* hashes, |
+ std::string* report_uri) { |
bool parsed_max_age = false; |
bool include_subdomains_candidate = false; |
uint32 max_age_candidate = 0; |
HashValueVector pins; |
- std::string source = value; |
+ HttpUtil::NameValuePairsIterator name_value_pairs( |
+ value.begin(), value.end(), ';', |
+ HttpUtil::NameValuePairsIterator::VALUES_OPTIONAL); |
- while (!source.empty()) { |
- StringPair semicolon = Split(source, ';'); |
- semicolon.first = Strip(semicolon.first); |
- semicolon.second = Strip(semicolon.second); |
- StringPair equals = Split(semicolon.first, '='); |
- equals.first = Strip(equals.first); |
- equals.second = Strip(equals.second); |
- |
- if (base::LowerCaseEqualsASCII(equals.first, "max-age")) { |
- if (equals.second.empty() || |
- !MaxAgeToInt(equals.second.begin(), equals.second.end(), |
- &max_age_candidate)) { |
+ while (name_value_pairs.GetNext()) { |
+ if (base::LowerCaseEqualsASCII(name_value_pairs.name(), "max-age")) { |
+ if (name_value_pairs.value().empty() || |
+ !MaxAgeToInt(name_value_pairs.value_begin(), |
+ name_value_pairs.value_end(), &max_age_candidate)) { |
return false; |
} |
parsed_max_age = true; |
- } else if (base::LowerCaseEqualsASCII(equals.first, "pin-sha1")) { |
- if (!ParseAndAppendPin(equals.second, HASH_VALUE_SHA1, &pins)) |
+ } else if (base::LowerCaseEqualsASCII(name_value_pairs.name(), |
+ "pin-sha1")) { |
+ if (!ParseAndAppendPin(name_value_pairs.raw_value(), HASH_VALUE_SHA1, |
+ &pins)) { |
return false; |
- } else if (base::LowerCaseEqualsASCII(equals.first, "pin-sha256")) { |
- if (!ParseAndAppendPin(equals.second, HASH_VALUE_SHA256, &pins)) |
+ } |
+ } else if (base::LowerCaseEqualsASCII(name_value_pairs.name(), |
+ "pin-sha256")) { |
+ if (!ParseAndAppendPin(name_value_pairs.raw_value(), HASH_VALUE_SHA256, |
+ &pins)) { |
return false; |
- } else if (base::LowerCaseEqualsASCII(equals.first, "includesubdomains")) { |
+ } |
+ } else if (base::LowerCaseEqualsASCII(name_value_pairs.name(), |
+ "includesubdomains")) { |
include_subdomains_candidate = true; |
+ } else if (base::LowerCaseEqualsASCII(name_value_pairs.name(), |
+ "report-uri")) { |
+ // report-uris are always quoted. |
+ if (name_value_pairs.raw_value().empty() || |
+ !HttpUtil::IsQuote(name_value_pairs.raw_value()[0]) || |
davidben
2015/07/15 22:21:06
Maybe expose value_is_quoted() out of NameValuePai
estark
2015/07/16 00:07:01
Done.
|
+ name_value_pairs.raw_value()[0] != |
+ *name_value_pairs.raw_value().rbegin()) { |
+ return false; |
+ } |
+ |
+ *report_uri = HttpUtil::Unquote(name_value_pairs.value()); |
davidben
2015/07/15 22:21:06
Bug? I think this should be Unquote(raw_value) or
estark
2015/07/16 00:07:00
Done.
|
+ if (report_uri->empty()) |
+ return false; |
} else { |
// Silently ignore unknown directives for forward compatibility. |
} |
- |
- source = semicolon.second; |
} |
+ if (!name_value_pairs.valid()) |
+ return false; |
+ |
if (!parsed_max_age) |
return false; |