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

Side by Side Diff: net/http/http_security_headers.cc

Issue 2753703002: Add Expect-CT header parsing (Closed)
Patch Set: mattm comments Created 3 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <limits> 5 #include <limits>
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/strings/string_piece.h" 8 #include "base/strings/string_piece.h"
9 #include "base/strings/string_tokenizer.h" 9 #include "base/strings/string_tokenizer.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 bool ParseHPKPReportOnlyHeader(const std::string& value, 358 bool ParseHPKPReportOnlyHeader(const std::string& value,
359 bool* include_subdomains, 359 bool* include_subdomains,
360 HashValueVector* hashes, 360 HashValueVector* hashes,
361 GURL* report_uri) { 361 GURL* report_uri) {
362 // max-age is irrelevant for Report-Only headers. 362 // max-age is irrelevant for Report-Only headers.
363 base::TimeDelta unused_max_age; 363 base::TimeDelta unused_max_age;
364 return ParseHPKPHeaderImpl(value, DO_NOT_REQUIRE_MAX_AGE, &unused_max_age, 364 return ParseHPKPHeaderImpl(value, DO_NOT_REQUIRE_MAX_AGE, &unused_max_age,
365 include_subdomains, hashes, report_uri); 365 include_subdomains, hashes, report_uri);
366 } 366 }
367 367
368 // "Expect-CT" ":"
369 // "max-age" "=" delta-seconds
370 // [ "," "enforce" ]
371 // [ "," "report-uri" "=" uri-reference ]
372 bool ParseExpectCTHeader(const std::string& value,
373 base::TimeDelta* max_age,
374 bool* enforce,
375 GURL* report_uri) {
376 bool parsed_max_age = false;
377 bool enforce_candidate = false;
378 bool has_report_uri = false;
379 uint32_t max_age_candidate = 0;
380 GURL parsed_report_uri;
381
382 HttpUtil::NameValuePairsIterator name_value_pairs(
383 value.begin(), value.end(), ',',
384 HttpUtil::NameValuePairsIterator::Values::NOT_REQUIRED,
385 // Use STRICT_QUOTES because "UAs must not attempt to fix malformed header
386 // fields."
387 HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES);
388
389 while (name_value_pairs.GetNext()) {
390 base::StringPiece name(name_value_pairs.name_begin(),
391 name_value_pairs.name_end());
392 if (base::LowerCaseEqualsASCII(name, "max-age")) {
393 // "A given directive MUST NOT appear more than once in a given header
394 // field."
395 if (parsed_max_age)
396 return false;
397 if (!MaxAgeToLimitedInt(name_value_pairs.value_begin(),
398 name_value_pairs.value_end(), kMaxExpectCTAgeSecs,
399 &max_age_candidate)) {
400 return false;
401 }
402 parsed_max_age = true;
403 } else if (base::LowerCaseEqualsASCII(name, "enforce")) {
404 // "A given directive MUST NOT appear more than once in a given header
405 // field."
406 if (enforce_candidate)
407 return false;
408 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.
409 return false;
410 }
411 enforce_candidate = true;
412 } else if (base::LowerCaseEqualsASCII(name, "report-uri")) {
413 // "A given directive MUST NOT appear more than once in a given header
414 // field."
415 if (has_report_uri)
416 return false;
417 // report-uris are always quoted.
418 if (!name_value_pairs.value_is_quoted())
419 return false;
420
421 has_report_uri = true;
422 parsed_report_uri = GURL(base::StringPiece(name_value_pairs.value_begin(),
423 name_value_pairs.value_end()));
424 if (parsed_report_uri.is_empty() || !parsed_report_uri.is_valid())
425 return false;
426 } else {
427 // Silently ignore unknown directives for forward compatibility.
428 }
429 }
430
431 if (!name_value_pairs.valid())
432 return false;
433
434 if (!parsed_max_age)
435 return false;
436
437 *max_age = base::TimeDelta::FromSeconds(max_age_candidate);
438 *enforce = enforce_candidate;
439 *report_uri = parsed_report_uri;
440 return true;
441 }
442
368 } // namespace net 443 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698