// Copyright (c) 2013 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 "quic/core/crypto/common_cert_set.h"

#include <cstddef>

#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "quic/core/quic_utils.h"

namespace quic {

namespace common_cert_set_2 {
#include "quic/core/crypto/common_cert_set_2.c"
}

namespace common_cert_set_3 {
#include "quic/core/crypto/common_cert_set_3.c"
}

namespace {

struct CertSet {
  // num_certs contains the number of certificates in this set.
  size_t num_certs;
  // certs is an array of |num_certs| pointers to the DER encoded certificates.
  const unsigned char* const* certs;
  // lens is an array of |num_certs| integers describing the length, in bytes,
  // of each certificate.
  const size_t* lens;
  // hash contains the 64-bit, FNV-1a hash of this set.
  uint64_t hash;
};

const CertSet kSets[] = {
    {
        common_cert_set_2::kNumCerts,
        common_cert_set_2::kCerts,
        common_cert_set_2::kLens,
        common_cert_set_2::kHash,
    },
    {
        common_cert_set_3::kNumCerts,
        common_cert_set_3::kCerts,
        common_cert_set_3::kLens,
        common_cert_set_3::kHash,
    },
};

const uint64_t kSetHashes[] = {
    common_cert_set_2::kHash,
    common_cert_set_3::kHash,
};

// Compare returns a value less than, equal to or greater than zero if |a| is
// lexicographically less than, equal to or greater than |b|, respectively.
int Compare(absl::string_view a, const unsigned char* b, size_t b_len) {
  size_t len = a.size();
  if (len > b_len) {
    len = b_len;
  }
  int n = memcmp(a.data(), b, len);
  if (n != 0) {
    return n;
  }

  if (a.size() < b_len) {
    return -1;
  } else if (a.size() > b_len) {
    return 1;
  }
  return 0;
}

// CommonCertSetsQUIC implements the CommonCertSets interface using the default
// certificate sets.
class CommonCertSetsQUIC : public CommonCertSets {
 public:
  // CommonCertSets interface.
  absl::string_view GetCommonHashes() const override {
    return absl::string_view(reinterpret_cast<const char*>(kSetHashes),
                             sizeof(uint64_t) * ABSL_ARRAYSIZE(kSetHashes));
  }

  absl::string_view GetCert(uint64_t hash, uint32_t index) const override {
    for (size_t i = 0; i < ABSL_ARRAYSIZE(kSets); i++) {
      if (kSets[i].hash == hash) {
        if (index < kSets[i].num_certs) {
          return absl::string_view(
              reinterpret_cast<const char*>(kSets[i].certs[index]),
              kSets[i].lens[index]);
        }
        break;
      }
    }

    return absl::string_view();
  }

  bool MatchCert(absl::string_view cert,
                 absl::string_view common_set_hashes,
                 uint64_t* out_hash,
                 uint32_t* out_index) const override {
    if (common_set_hashes.size() % sizeof(uint64_t) != 0) {
      return false;
    }

    for (size_t i = 0; i < common_set_hashes.size() / sizeof(uint64_t); i++) {
      uint64_t hash;
      memcpy(&hash, common_set_hashes.data() + i * sizeof(uint64_t),
             sizeof(uint64_t));

      for (size_t j = 0; j < ABSL_ARRAYSIZE(kSets); j++) {
        if (kSets[j].hash != hash) {
          continue;
        }

        if (kSets[j].num_certs == 0) {
          continue;
        }

        // Binary search for a matching certificate.
        size_t min = 0;
        size_t max = kSets[j].num_certs - 1;
        while (max >= min) {
          size_t mid = min + ((max - min) / 2);
          int n = Compare(cert, kSets[j].certs[mid], kSets[j].lens[mid]);
          if (n < 0) {
            if (mid == 0) {
              break;
            }
            max = mid - 1;
          } else if (n > 0) {
            min = mid + 1;
          } else {
            *out_hash = hash;
            *out_index = mid;
            return true;
          }
        }
      }
    }

    return false;
  }

  CommonCertSetsQUIC() {}
  CommonCertSetsQUIC(const CommonCertSetsQUIC&) = delete;
  CommonCertSetsQUIC& operator=(const CommonCertSetsQUIC&) = delete;
  ~CommonCertSetsQUIC() override {}
};

}  // anonymous namespace

CommonCertSets::~CommonCertSets() {}

// static
const CommonCertSets* CommonCertSets::GetInstanceQUIC() {
  static CommonCertSetsQUIC* certs = new CommonCertSetsQUIC();
  return certs;
}

}  // namespace quic
