// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <limits>

#include "base/base64.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "net/base/parse_number.h"
#include "net/http/http_security_headers.h"
#include "net/http/http_util.h"
#include "url/gurl.h"

namespace net {

namespace {

enum MaxAgeParsing { REQUIRE_MAX_AGE, DO_NOT_REQUIRE_MAX_AGE };

// MaxAgeToLimitedInt converts a string representation of a "whole number" of
// seconds into a uint32_t. The string may contain an arbitrarily large number,
// which will be clipped to a supplied limit and which is guaranteed to fit
// within a 32-bit unsigned integer. False is returned on any parse error.
bool MaxAgeToLimitedInt(std::string::const_iterator begin,
                        std::string::const_iterator end,
                        uint32_t limit,
                        uint32_t* result) {
  const base::StringPiece s(begin, end);

  ParseIntError error;
  if (!ParseUint32(s, result, &error)) {
    if (error == ParseIntError::FAILED_OVERFLOW) {
      *result = limit;
    } else {
      return false;
    }
  }

  if (*result > limit)
    *result = limit;

  return true;
}

// Returns true iff there is an item in |pins| which is not present in
// |from_cert_chain|. Such an SPKI hash is called a "backup pin".
bool IsBackupPinPresent(const HashValueVector& pins,
                        const HashValueVector& from_cert_chain) {
  for (const auto& pin : pins) {
    auto p = std::find(from_cert_chain.begin(), from_cert_chain.end(), pin);
    if (p == from_cert_chain.end())
      return true;
  }
  return false;
}

// Returns true if the intersection of |a| and |b| is not empty. If either
// |a| or |b| is empty, returns false.
bool HashesIntersect(const HashValueVector& a,
                     const HashValueVector& b) {
  for (const auto& pin : a) {
    auto p = std::find(b.begin(), b.end(), pin);
    if (p != b.end())
      return true;
  }
  return false;
}

// Returns true iff |pins| contains both a live and a backup pin. A live pin
// is a pin whose SPKI is present in the certificate chain in |ssl_info|. A
// backup pin is a pin intended for disaster recovery, not day-to-day use, and
// thus must be absent from the certificate chain. The Public-Key-Pins header
// specification requires both.
bool IsPinListValid(const HashValueVector& pins,
                    const HashValueVector& from_cert_chain) {
  // Fast fail: 1 live + 1 backup = at least 2 pins. (Check for actual
  // liveness and backupness below.)
  if (pins.size() < 2)
    return false;

  if (from_cert_chain.empty())
    return false;

  return IsBackupPinPresent(pins, from_cert_chain) &&
         HashesIntersect(pins, from_cert_chain);
}

bool ParseAndAppendPin(std::string::const_iterator begin,
                       std::string::const_iterator end,
                       HashValueTag tag,
                       HashValueVector* hashes) {
  const base::StringPiece value(begin, end);
  if (value.empty())
    return false;

  std::string decoded;
  if (!base::Base64Decode(value, &decoded))
    return false;

  HashValue hash(tag);
  if (decoded.size() != hash.size())
    return false;

  memcpy(hash.data(), decoded.data(), hash.size());
  hashes->push_back(hash);
  return true;
}

bool ParseHPKPHeaderImpl(const std::string& value,
                         MaxAgeParsing max_age_status,
                         base::TimeDelta* max_age,
                         bool* include_subdomains,
                         HashValueVector* hashes,
                         GURL* report_uri) {
  bool parsed_max_age = false;
  bool include_subdomains_candidate = false;
  uint32_t max_age_candidate = 0;
  GURL parsed_report_uri;
  HashValueVector pins;
  bool require_max_age = max_age_status == REQUIRE_MAX_AGE;

  HttpUtil::NameValuePairsIterator name_value_pairs(
      value.begin(), value.end(), ';',
      HttpUtil::NameValuePairsIterator::Values::NOT_REQUIRED,
      HttpUtil::NameValuePairsIterator::Quotes::NOT_STRICT);

  while (name_value_pairs.GetNext()) {
    if (base::LowerCaseEqualsASCII(
            base::StringPiece(name_value_pairs.name_begin(),
                              name_value_pairs.name_end()),
            "max-age")) {
      if (!MaxAgeToLimitedInt(name_value_pairs.value_begin(),
                              name_value_pairs.value_end(), kMaxHPKPAgeSecs,
                              &max_age_candidate)) {
        return false;
      }
      parsed_max_age = true;
    } else if (base::LowerCaseEqualsASCII(
                   base::StringPiece(name_value_pairs.name_begin(),
                                     name_value_pairs.name_end()),
                   "pin-sha256")) {
      // Pins are always quoted.
      if (!name_value_pairs.value_is_quoted() ||
          !ParseAndAppendPin(name_value_pairs.value_begin(),
                             name_value_pairs.value_end(), HASH_VALUE_SHA256,
                             &pins)) {
        return false;
      }
    } else if (base::LowerCaseEqualsASCII(
                   base::StringPiece(name_value_pairs.name_begin(),
                                     name_value_pairs.name_end()),
                   "includesubdomains")) {
      include_subdomains_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());
      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 && require_max_age)
    return false;

  *max_age = base::TimeDelta::FromSeconds(max_age_candidate);
  *include_subdomains = include_subdomains_candidate;
  hashes->swap(pins);
  *report_uri = parsed_report_uri;

  return true;
}

}  // namespace

// Parse the Strict-Transport-Security header, as currently defined in
// http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-14:
//
// Strict-Transport-Security = "Strict-Transport-Security" ":"
//                             [ directive ]  *( ";" [ directive ] )
//
// directive                 = directive-name [ "=" directive-value ]
// directive-name            = token
// directive-value           = token | quoted-string
//
// 1.  The order of appearance of directives is not significant.
//
// 2.  All directives MUST appear only once in an STS header field.
//     Directives are either optional or required, as stipulated in
//     their definitions.
//
// 3.  Directive names are case-insensitive.
//
// 4.  UAs MUST ignore any STS header fields containing directives, or
//     other header field value data, that does not conform to the
//     syntax defined in this specification.
//
// 5.  If an STS header field contains directive(s) not recognized by
//     the UA, the UA MUST ignore the unrecognized directives and if the
//     STS header field otherwise satisfies the above requirements (1
//     through 4), the UA MUST process the recognized directives.
bool ParseHSTSHeader(const std::string& value,
                     base::TimeDelta* max_age,
                     bool* include_subdomains) {
  uint32_t max_age_candidate = 0;
  bool include_subdomains_candidate = false;

  // We must see max-age exactly once.
  int max_age_observed = 0;
  // We must see includeSubdomains exactly 0 or 1 times.
  int include_subdomains_observed = 0;

  enum ParserState {
    START,
    AFTER_MAX_AGE_LABEL,
    AFTER_MAX_AGE_EQUALS,
    AFTER_MAX_AGE,
    AFTER_INCLUDE_SUBDOMAINS,
    AFTER_UNKNOWN_LABEL,
    DIRECTIVE_END
  } state = START;

  base::StringTokenizer tokenizer(value, " \t=;");
  tokenizer.set_options(base::StringTokenizer::RETURN_DELIMS);
  tokenizer.set_quote_chars("\"");
  std::string unquoted;
  while (tokenizer.GetNext()) {
    DCHECK(!tokenizer.token_is_delim() || tokenizer.token().length() == 1);
    switch (state) {
      case START:
      case DIRECTIVE_END:
        if (base::IsAsciiWhitespace(*tokenizer.token_begin()))
          continue;
        if (base::LowerCaseEqualsASCII(tokenizer.token(), "max-age")) {
          state = AFTER_MAX_AGE_LABEL;
          max_age_observed++;
        } else if (base::LowerCaseEqualsASCII(tokenizer.token(),
                                              "includesubdomains")) {
          state = AFTER_INCLUDE_SUBDOMAINS;
          include_subdomains_observed++;
          include_subdomains_candidate = true;
        } else {
          state = AFTER_UNKNOWN_LABEL;
        }
        break;

      case AFTER_MAX_AGE_LABEL:
        if (base::IsAsciiWhitespace(*tokenizer.token_begin()))
          continue;
        if (*tokenizer.token_begin() != '=')
          return false;
        DCHECK_EQ(tokenizer.token().length(), 1U);
        state = AFTER_MAX_AGE_EQUALS;
        break;

      case AFTER_MAX_AGE_EQUALS:
        if (base::IsAsciiWhitespace(*tokenizer.token_begin()))
          continue;
        unquoted = HttpUtil::Unquote(tokenizer.token());
        if (!MaxAgeToLimitedInt(unquoted.begin(), unquoted.end(),
                                kMaxHSTSAgeSecs, &max_age_candidate))
          return false;
        state = AFTER_MAX_AGE;
        break;

      case AFTER_MAX_AGE:
      case AFTER_INCLUDE_SUBDOMAINS:
        if (base::IsAsciiWhitespace(*tokenizer.token_begin()))
          continue;
        else if (*tokenizer.token_begin() == ';')
          state = DIRECTIVE_END;
        else
          return false;
        break;

      case AFTER_UNKNOWN_LABEL:
        // Consume and ignore the post-label contents (if any).
        if (*tokenizer.token_begin() != ';')
          continue;
        state = DIRECTIVE_END;
        break;
    }
  }

  // We've consumed all the input. Let's see what state we ended up in.
  if (max_age_observed != 1 ||
      (include_subdomains_observed != 0 && include_subdomains_observed != 1)) {
    return false;
  }

  switch (state) {
    case DIRECTIVE_END:
    case AFTER_MAX_AGE:
    case AFTER_INCLUDE_SUBDOMAINS:
    case AFTER_UNKNOWN_LABEL:
      *max_age = base::TimeDelta::FromSeconds(max_age_candidate);
      *include_subdomains = include_subdomains_candidate;
      return true;
    case START:
    case AFTER_MAX_AGE_LABEL:
    case AFTER_MAX_AGE_EQUALS:
      return false;
    default:
      NOTREACHED();
      return false;
  }
}

// "Public-Key-Pins" ":"
//     "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,
                     GURL* report_uri) {
  base::TimeDelta candidate_max_age;
  bool candidate_include_subdomains;
  HashValueVector candidate_hashes;
  GURL candidate_report_uri;

  if (!ParseHPKPHeaderImpl(value, REQUIRE_MAX_AGE, &candidate_max_age,
                           &candidate_include_subdomains, &candidate_hashes,
                           &candidate_report_uri)) {
    return false;
  }

  if (!IsPinListValid(candidate_hashes, chain_hashes))
    return false;

  *max_age = candidate_max_age;
  *include_subdomains = candidate_include_subdomains;
  hashes->swap(candidate_hashes);
  *report_uri = candidate_report_uri;
  return true;
}

// "Public-Key-Pins-Report-Only" ":"
//     [ "max-age" "=" delta-seconds ";" ]
//     "pin-" algo "=" base64 [ ";" ... ]
//     [ ";" "includeSubdomains" ]
//     [ ";" "report-uri" "=" uri-reference ]
bool ParseHPKPReportOnlyHeader(const std::string& value,
                               bool* include_subdomains,
                               HashValueVector* hashes,
                               GURL* report_uri) {
  // max-age is irrelevant for Report-Only headers.
  base::TimeDelta unused_max_age;
  return ParseHPKPHeaderImpl(value, DO_NOT_REQUIRE_MAX_AGE, &unused_max_age,
                             include_subdomains, hashes, report_uri);
}

}  // namespace net
