// Copyright 2020 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 "net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h"

#include <cstdint>
#include <memory>

#include "absl/strings/string_view.h"
#include "third_party/boringssl/src/include/openssl/sha.h"
#include "net/third_party/quiche/src/quic/core/crypto/certificate_view.h"
#include "net/third_party/quiche/src/quic/core/quic_time.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"

namespace quic {
namespace {

constexpr size_t kFingerprintLength = SHA256_DIGEST_LENGTH * 3 - 1;

constexpr std::array<char, 16> kHexDigits = {'0', '1', '2', '3', '4', '5',
                                             '6', '7', '8', '9', 'a', 'b',
                                             'c', 'd', 'e', 'f'};

// Assumes that the character is normalized to lowercase beforehand.
bool IsNormalizedHexDigit(char c) {
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
}

void NormalizeFingerprint(CertificateFingerprint& fingerprint) {
  fingerprint.fingerprint =
      quiche::QuicheTextUtils::ToLower(fingerprint.fingerprint);
}

}  // namespace

constexpr char CertificateFingerprint::kSha256[];

std::string ComputeSha256Fingerprint(absl::string_view input) {
  std::vector<uint8_t> raw_hash;
  raw_hash.resize(SHA256_DIGEST_LENGTH);
  SHA256(reinterpret_cast<const uint8_t*>(input.data()), input.size(),
         raw_hash.data());

  std::string output;
  output.resize(kFingerprintLength);
  for (size_t i = 0; i < output.size(); i++) {
    uint8_t hash_byte = raw_hash[i / 3];
    switch (i % 3) {
      case 0:
        output[i] = kHexDigits[hash_byte >> 4];
        break;
      case 1:
        output[i] = kHexDigits[hash_byte & 0xf];
        break;
      case 2:
        output[i] = ':';
        break;
    }
  }
  return output;
}

ProofVerifyDetails* WebTransportFingerprintProofVerifier::Details::Clone()
    const {
  return new Details(*this);
}

WebTransportFingerprintProofVerifier::WebTransportFingerprintProofVerifier(
    const QuicClock* clock,
    int max_validity_days)
    : clock_(clock),
      max_validity_days_(max_validity_days),
      // Add an extra second to max validity to accomodate various edge cases.
      max_validity_(
          QuicTime::Delta::FromSeconds(max_validity_days * 86400 + 1)) {}

bool WebTransportFingerprintProofVerifier::AddFingerprint(
    CertificateFingerprint fingerprint) {
  NormalizeFingerprint(fingerprint);
  if (fingerprint.algorithm != CertificateFingerprint::kSha256) {
    QUIC_DLOG(WARNING) << "Algorithms other than SHA-256 are not supported";
    return false;
  }
  if (fingerprint.fingerprint.size() != kFingerprintLength) {
    QUIC_DLOG(WARNING) << "Invalid fingerprint length";
    return false;
  }
  for (size_t i = 0; i < fingerprint.fingerprint.size(); i++) {
    char current = fingerprint.fingerprint[i];
    if (i % 3 == 2) {
      if (current != ':') {
        QUIC_DLOG(WARNING)
            << "Missing colon separator between the bytes of the hash";
        return false;
      }
    } else {
      if (!IsNormalizedHexDigit(current)) {
        QUIC_DLOG(WARNING) << "Fingerprint must be in hexadecimal";
        return false;
      }
    }
  }

  fingerprints_.push_back(fingerprint);
  return true;
}

QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyProof(
    const std::string& /*hostname*/,
    const uint16_t /*port*/,
    const std::string& /*server_config*/,
    QuicTransportVersion /*transport_version*/,
    absl::string_view /*chlo_hash*/,
    const std::vector<std::string>& /*certs*/,
    const std::string& /*cert_sct*/,
    const std::string& /*signature*/,
    const ProofVerifyContext* /*context*/,
    std::string* error_details,
    std::unique_ptr<ProofVerifyDetails>* details,
    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
  *error_details =
      "QUIC crypto certificate verification is not supported in "
      "WebTransportFingerprintProofVerifier";
  QUIC_BUG << *error_details;
  *details = std::make_unique<Details>(Status::kInternalError);
  return QUIC_FAILURE;
}

QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain(
    const std::string& /*hostname*/,
    const uint16_t /*port*/,
    const std::vector<std::string>& certs,
    const std::string& /*ocsp_response*/,
    const std::string& /*cert_sct*/,
    const ProofVerifyContext* /*context*/,
    std::string* error_details,
    std::unique_ptr<ProofVerifyDetails>* details,
    std::unique_ptr<ProofVerifierCallback> /*callback*/) {
  if (certs.empty()) {
    *details = std::make_unique<Details>(Status::kInternalError);
    *error_details = "No certificates provided";
    return QUIC_FAILURE;
  }

  if (!HasKnownFingerprint(certs[0])) {
    *details = std::make_unique<Details>(Status::kUnknownFingerprint);
    *error_details = "Certificate does not match any fingerprint";
    return QUIC_FAILURE;
  }

  std::unique_ptr<CertificateView> view =
      CertificateView::ParseSingleCertificate(certs[0]);
  if (view == nullptr) {
    *details = std::make_unique<Details>(Status::kCertificateParseFailure);
    *error_details = "Failed to parse the certificate";
    return QUIC_FAILURE;
  }

  if (!HasValidExpiry(*view)) {
    *details = std::make_unique<Details>(Status::kExpiryTooLong);
    *error_details = quiche::QuicheStrCat(
        "Certificate expiry exceeds the configured limit of ",
        max_validity_days_, " days");
    return QUIC_FAILURE;
  }

  if (!IsWithinValidityPeriod(*view)) {
    *details = std::make_unique<Details>(Status::kExpired);
    *error_details =
        "Certificate has expired or has validity listed in the future";
    return QUIC_FAILURE;
  }

  *details = std::make_unique<Details>(Status::kValidCertificate);
  return QUIC_SUCCESS;
}

std::unique_ptr<ProofVerifyContext>
WebTransportFingerprintProofVerifier::CreateDefaultContext() {
  return nullptr;
}

bool WebTransportFingerprintProofVerifier::HasKnownFingerprint(
    absl::string_view der_certificate) {
  // https://wicg.github.io/web-transport/#verify-a-certificate-fingerprint
  const std::string fingerprint = ComputeSha256Fingerprint(der_certificate);
  for (const CertificateFingerprint& reference : fingerprints_) {
    if (reference.algorithm != CertificateFingerprint::kSha256) {
      QUIC_BUG << "Unexpected non-SHA-256 hash";
      continue;
    }
    if (fingerprint == reference.fingerprint) {
      return true;
    }
  }
  return false;
}

bool WebTransportFingerprintProofVerifier::HasValidExpiry(
    const CertificateView& certificate) {
  if (!certificate.validity_start().IsBefore(certificate.validity_end())) {
    return false;
  }

  const QuicTime::Delta duration_seconds =
      certificate.validity_end() - certificate.validity_start();
  return duration_seconds <= max_validity_;
}

bool WebTransportFingerprintProofVerifier::IsWithinValidityPeriod(
    const CertificateView& certificate) {
  QuicWallTime now = clock_->WallNow();
  return now.IsAfter(certificate.validity_start()) &&
         now.IsBefore(certificate.validity_end());
}

}  // namespace quic
