Chromium Code Reviews| Index: net/http/http_security_headers.cc |
| diff --git a/net/http/http_security_headers.cc b/net/http/http_security_headers.cc |
| index 8225385ee8a5772c472ae617822d6143fa246dec..d8317037c8de42afb9c9f3b5b72c413815b626c6 100644 |
| --- a/net/http/http_security_headers.cc |
| +++ b/net/http/http_security_headers.cc |
| @@ -365,4 +365,79 @@ bool ParseHPKPReportOnlyHeader(const std::string& value, |
| include_subdomains, hashes, report_uri); |
| } |
| +// "Expect-CT" ":" |
| +// "max-age" "=" delta-seconds |
| +// [ "," "enforce" ] |
| +// [ "," "report-uri" "=" uri-reference ] |
| +bool ParseExpectCTHeader(const std::string& value, |
| + base::TimeDelta* max_age, |
| + bool* enforce, |
| + GURL* report_uri) { |
| + bool parsed_max_age = false; |
| + bool enforce_candidate = false; |
| + bool has_report_uri = false; |
| + uint32_t max_age_candidate = 0; |
| + GURL parsed_report_uri; |
| + |
| + HttpUtil::NameValuePairsIterator name_value_pairs( |
| + value.begin(), value.end(), ',', |
| + HttpUtil::NameValuePairsIterator::Values::NOT_REQUIRED, |
| + // Use STRICT_QUOTES because "UAs must not attempt to fix malformed header |
| + // fields." |
| + HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES); |
| + |
| + while (name_value_pairs.GetNext()) { |
| + base::StringPiece name(name_value_pairs.name_begin(), |
| + name_value_pairs.name_end()); |
| + if (base::LowerCaseEqualsASCII(name, "max-age")) { |
| + // "A given directive MUST NOT appear more than once in a given header |
| + // field." |
| + if (parsed_max_age) |
| + return false; |
| + if (!MaxAgeToLimitedInt(name_value_pairs.value_begin(), |
| + name_value_pairs.value_end(), kMaxExpectCTAgeSecs, |
| + &max_age_candidate)) { |
| + return false; |
| + } |
| + parsed_max_age = true; |
| + } else if (base::LowerCaseEqualsASCII(name, "enforce")) { |
| + // "A given directive MUST NOT appear more than once in a given header |
| + // field." |
| + if (enforce_candidate) |
| + return false; |
| + if (!name_value_pairs.value().empty()) { |
|
mattm
2017/04/21 05:15:53
nit: don't need the braces on this one
estark
2017/04/21 16:37:31
Done.
|
| + return false; |
| + } |
| + enforce_candidate = true; |
| + } else if (base::LowerCaseEqualsASCII(name, "report-uri")) { |
| + // "A given directive MUST NOT appear more than once in a given header |
| + // field." |
| + if (has_report_uri) |
| + return false; |
| + // report-uris are always quoted. |
| + if (!name_value_pairs.value_is_quoted()) |
| + return false; |
| + |
| + has_report_uri = true; |
| + parsed_report_uri = GURL(base::StringPiece(name_value_pairs.value_begin(), |
| + name_value_pairs.value_end())); |
| + if (parsed_report_uri.is_empty() || !parsed_report_uri.is_valid()) |
| + return false; |
| + } else { |
| + // Silently ignore unknown directives for forward compatibility. |
| + } |
| + } |
| + |
| + if (!name_value_pairs.valid()) |
| + return false; |
| + |
| + if (!parsed_max_age) |
| + return false; |
| + |
| + *max_age = base::TimeDelta::FromSeconds(max_age_candidate); |
| + *enforce = enforce_candidate; |
| + *report_uri = parsed_report_uri; |
| + return true; |
| +} |
| + |
| } // namespace net |