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

Unified Diff: net/http/http_security_headers.cc

Issue 1211363005: Parse HPKP report-uri and persist in TransportSecurityPersister (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: davidben comments Created 5 years, 5 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 side-by-side diff with in-line comments
Download patch
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..1dd01bb690eaf6ddd21d2dbe5f6d7beb1fdb2ab4 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,66 @@ 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;
-
- 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);
+ HttpUtil::NameValuePairsIterator name_value_pairs(
+ value.begin(), value.end(), ';',
+ HttpUtil::NameValuePairsIterator::VALUES_OPTIONAL);
- 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() ||
Ryan Sleevi 2015/07/16 02:25:44 It's worth noting that you force a string coercion
estark 2015/07/16 04:52:18 Done.
+ !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,
Ryan Sleevi 2015/07/16 02:25:44 Man, never realized how many copies we were making
estark 2015/07/16 04:52:18 Done, I think -- please check and make sure I did
+ &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.value_is_quoted())
+ return false;
+
+ *report_uri = name_value_pairs.value();
+ if (report_uri->empty())
+ return false;
Ryan Sleevi 2015/07/16 02:25:44 So this makes me a little uncomfortable, because u
Ryan Sleevi 2015/07/16 02:25:44 BUG: We parse the other fields for validity and co
estark 2015/07/16 04:52:18 Done.
estark 2015/07/16 04:52:18 Ah, good point... Done. I'm now passing around GUR
} else {
// Silently ignore unknown directives for forward compatibility.
}
-
- source = semicolon.second;
}
+ if (!name_value_pairs.valid())
+ return false;
+
if (!parsed_max_age)
return false;

Powered by Google App Engine
This is Rietveld 408576698