// Copyright (c) 2016 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/proof_source.h"

#include <string>

#include "quic/platform/api/quic_bug_tracker.h"

namespace quic {

CryptoBuffers::~CryptoBuffers() {
  for (size_t i = 0; i < value.size(); i++) {
    CRYPTO_BUFFER_free(value[i]);
  }
}

ProofSource::Chain::Chain(const std::vector<std::string>& certs)
    : certs(certs) {}

ProofSource::Chain::~Chain() {}

CryptoBuffers ProofSource::Chain::ToCryptoBuffers() const {
  CryptoBuffers crypto_buffers;
  crypto_buffers.value.reserve(certs.size());
  for (size_t i = 0; i < certs.size(); i++) {
    crypto_buffers.value.push_back(
        CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(certs[i].data()),
                          certs[i].length(), nullptr));
  }
  return crypto_buffers;
}

bool ValidateCertAndKey(
    const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
    const CertificatePrivateKey& key) {
  if (chain.get() == nullptr || chain->certs.empty()) {
    QUIC_BUG(quic_proof_source_empty_chain) << "Certificate chain is empty";
    return false;
  }

  std::unique_ptr<CertificateView> leaf =
      CertificateView::ParseSingleCertificate(chain->certs[0]);
  if (leaf == nullptr) {
    QUIC_BUG(quic_proof_source_unparsable_leaf_cert)
        << "Unabled to parse leaf certificate";
    return false;
  }

  if (!key.MatchesPublicKey(*leaf)) {
    QUIC_BUG(quic_proof_source_key_mismatch)
        << "Private key does not match the leaf certificate";
    return false;
  }
  return true;
}

}  // namespace quic
