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..3e187c4ffc1cc9fc41a80bc43aa8b3a6e2566664 100644 |
--- a/net/http/http_security_headers.cc |
+++ b/net/http/http_security_headers.cc |
@@ -365,4 +365,66 @@ 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; |
+ uint32_t max_age_candidate = 0; |
+ GURL parsed_report_uri; |
+ |
+ HttpUtil::NameValuePairsIterator name_value_pairs( |
+ value.begin(), value.end(), ',', |
mattm
2017/04/20 05:48:29
Am I reading the draft wrong or does it define the
estark
2017/04/20 22:36:08
No, my bad, I haven't published an updated draft s
|
+ HttpUtil::NameValuePairsIterator::Values::NOT_REQUIRED, |
+ HttpUtil::NameValuePairsIterator::Quotes::NOT_STRICT); |
mattm
2017/04/20 05:48:29
should that be STRICT_QUOTES?
(from section 2.1 "
estark
2017/04/20 22:36:08
Done.
|
+ |
+ while (name_value_pairs.GetNext()) { |
+ if (base::LowerCaseEqualsASCII( |
+ base::StringPiece(name_value_pairs.name_begin(), |
+ name_value_pairs.name_end()), |
mattm
2017/04/20 05:48:29
could make this StringPiece once at the beginning
estark
2017/04/20 22:36:08
Done.
|
+ "max-age")) { |
+ if (!MaxAgeToLimitedInt(name_value_pairs.value_begin(), |
+ name_value_pairs.value_end(), kMaxExpectCTAgeSecs, |
+ &max_age_candidate)) { |
+ return false; |
+ } |
+ parsed_max_age = true; |
mattm
2017/04/20 05:48:29
should there be checks that each directive is only
estark
2017/04/20 22:36:08
Done.
|
+ } else if (base::LowerCaseEqualsASCII( |
+ base::StringPiece(name_value_pairs.name_begin(), |
+ name_value_pairs.name_end()), |
+ "enforce")) { |
mattm
2017/04/20 05:48:29
check that no value was given for enforce?
estark
2017/04/20 22:36:08
Done.
|
+ enforce_candidate = true; |
+ } else if (base::LowerCaseEqualsASCII( |
+ base::StringPiece(name_value_pairs.name_begin(), |
+ name_value_pairs.name_end()), |
+ "report-uri")) { |
+ // report-uris are always quoted. |
+ if (!name_value_pairs.value_is_quoted()) |
+ return false; |
+ |
+ parsed_report_uri = GURL(name_value_pairs.value()); |
mattm
2017/04/20 05:48:29
could use a StringPiece for the GURL param too
estark
2017/04/20 22:36:08
Done.
|
+ 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 |