// Copyright 2020 The Chromium OS 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 "hwsec-test-utils/verified_access/verified_access.h"

#include <string>
#include <utility>

#include <attestation/proto_bindings/attestation_ca.pb.h>
#include <base/logging.h>
#include <base/optional.h>
#include <crypto/scoped_openssl_types.h>

#include "hwsec-test-utils/common/attestation_crypto.h"
#include "hwsec-test-utils/common/openssl_utility.h"
#include "hwsec-test-utils/well_known_key_pairs/well_known_key_pairs.h"

namespace hwsec_test_utils {
namespace verified_access {

namespace {

constexpr int kNonceSize = 20;

base::Optional<std::string> GenerateNonce() {
  return GetRandom(kNonceSize);
}

base::Optional<attestation::KeyInfo> DecryptKeyInfo(
    const attestation::EncryptedData& encrypted_key_info) {
  crypto::ScopedEVP_PKEY key = well_known_key_pairs::GetVaEncryptionkey();

  std::string decrypted_data;
  attestation_crypto::ReturnStatus decrypt_status = attestation_crypto::Decrypt(
      encrypted_key_info, key, attestation_crypto::KeyDeriverDirect(),
      &decrypted_data);
  if (decrypt_status != attestation_crypto::ReturnStatus::kSuccess) {
    LOG(ERROR) << __func__
               << ": Failed to decrypt serialized key info; status code: "
               << static_cast<int>(decrypt_status);
    return {};
  }

  // Deserialize.
  attestation::KeyInfo key_info;
  if (!key_info.ParseFromString(decrypted_data)) {
    LOG(ERROR) << __func__ << ": Failed to parse |KeyInfo|.";
    return {};
  }
  return key_info;
}

bool VerifySPKAC(const attestation::KeyInfo& key_info) {
  auto asn1_ptr = reinterpret_cast<const unsigned char*>(
      key_info.signed_public_key_and_challenge().data());
  crypto::ScopedNETSCAPE_SPKI spki(d2i_NETSCAPE_SPKI(
      nullptr, &asn1_ptr, key_info.signed_public_key_and_challenge().length()));
  if (!spki) {
    LOG(ERROR) << __func__
               << ": Failed to call d2i_NETSCAPE_SPKI: " << GetOpenSSLError();
    return false;
  }

  // Verifies the SPKI with the key in the SPKI.
  crypto::ScopedEVP_PKEY key(NETSCAPE_SPKI_get_pubkey(spki.get()));
  if (!key) {
    LOG(ERROR) << __func__ << ": Failed to call NETSCAPE_SPKI_get_pubkey: "
               << GetOpenSSLError();
    return false;
  }

  crypto::ScopedX509 x509 = PemToX509(key_info.certificate());
  if (!x509) {
    LOG(ERROR) << __func__ << ": Failed to parse certificate.";
    return false;
  }

  if (NETSCAPE_SPKI_verify(spki.get(), key.get()) != 1) {
    LOG(ERROR) << __func__ << ": Failed to call NETSCAPE_SPKI_verify: "
               << GetOpenSSLError();
    return false;
  }

  crypto::ScopedEVP_PKEY key_in_cert(X509_get_pubkey(x509.get()));
  if (!key_in_cert) {
    LOG(ERROR) << __func__
               << ": Failed to call X509_get_pubkey: " << GetOpenSSLError();
    return false;
  }

  // It is intentional not to print any interpreted result because the
  // interpretation might be subject to change or extension with openssl version
  // being upgraded. Please look up the openssl document for the meaning.
  int compare_result;
  if ((compare_result = EVP_PKEY_cmp(key.get(), key_in_cert.get())) != 1) {
    LOG(ERROR) << __func__ << ": EVP_PKEY_cmp result: " << compare_result;
    return false;
  }
  return true;
}

}  // namespace

VerifiedAccessChallenge::VerifiedAccessChallenge() {
  InitializeOpenSSL();
}

base::Optional<attestation::SignedData>
VerifiedAccessChallenge::GenerateChallenge(const std::string& prefix) {
  // Generate the data to sign, including the prefix and a nonce.
  attestation::Challenge challenge;
  challenge.set_prefix(prefix);
  base::Optional<std::string> nonce = GenerateNonce();
  if (!nonce) {
    LOG(WARNING) << __func__ << ": Failed to generate nonce.";
    return {};
  }
  challenge.set_nonce(*nonce);
  std::string serialized_challenge;
  if (!challenge.SerializeToString(&serialized_challenge)) {
    LOG(ERROR) << __func__ << ": Failed to serialize challenge.";
    return {};
  }

  // Construct the return value, including the data and its signature.
  attestation::SignedData signed_data;
  signed_data.set_data(serialized_challenge);
  crypto::ScopedEVP_PKEY key = well_known_key_pairs::GetVaSigningkey();
  if (!key) {
    LOG(ERROR) << __func__ << ": Failed get the va signing key.";
    return {};
  }
  base::Optional<std::string> signature =
      EVPDigestSign(key, EVP_sha256(), serialized_challenge);
  if (!signature) {
    LOG(ERROR) << __func__ << ": Failed to sign the generated challenge.";
  }
  *signed_data.mutable_signature() = std::move(*signature);
  return signed_data;
}

bool VerifiedAccessChallenge::VerifyChallengeResponse(
    const attestation::SignedData& signed_challenge_response,
    const std::string& prefix) {
  attestation::ChallengeResponse challenge_response;
  if (!challenge_response.ParseFromString(signed_challenge_response.data())) {
    LOG(ERROR) << __func__ << ": Failed to parse |ChallengeResponse|";
    return false;
  }

  // Verify the nonce is set.
  if (challenge_response.nonce().empty()) {
    LOG(ERROR) << __func__ << ": no nonce in response.";
    return false;
  }

  // Verify the challenge has expected signature and prefix.
  crypto::ScopedEVP_PKEY google_signing_key =
      well_known_key_pairs::GetVaSigningkey();
  const attestation::SignedData& challenge_with_signature =
      challenge_response.challenge();
  if (!EVPDigestVerify(google_signing_key, EVP_sha256(),
                       challenge_with_signature.data(),
                       challenge_with_signature.signature())) {
    LOG(ERROR) << __func__ << ": challenge signature mismatch.";
    return false;
  }
  attestation::Challenge challenge;
  if (!challenge.ParseFromString(challenge_with_signature.data())) {
    LOG(ERROR) << __func__ << ": Failed to parse |Challenge|";
    return false;
  }
  if (challenge.prefix() != prefix) {
    LOG(ERROR) << __func__ << ": Prefix mismatch: " << challenge.prefix()
               << "(expected: " << prefix << ")";
    return false;
  }

  // Note that by design there is no verification against key_id since in the
  // testing we don't care.
  base::Optional<attestation::KeyInfo> key_info =
      DecryptKeyInfo(challenge_response.encrypted_key_info());
  if (!key_info) {
    LOG(ERROR) << __func__ << ": Failed to decrypt |KeyInfo|.";
    return false;
  }

  if (!VerifySPKAC(*key_info)) {
    LOG(ERROR) << __func__ << ": Failed to verify SPKAC.";
    return false;
  }

  crypto::ScopedX509 x509 = PemToX509(key_info->certificate());
  if (!x509) {
    LOG(ERROR) << __func__ << ": Failed to parse certificate.";
    return false;
  }

  // Verify response signature.
  crypto::ScopedEVP_PKEY key_in_cert(X509_get_pubkey(x509.get()));
  if (!key_in_cert) {
    LOG(ERROR) << __func__
               << ": Failed to call X509_get_pubkey: " << GetOpenSSLError();
    return false;
  }
  if (!EVPDigestVerify(key_in_cert, EVP_sha256(),
                       signed_challenge_response.data(),
                       signed_challenge_response.signature())) {
    LOG(ERROR) << __func__
               << ": Failed to verify signature of challenge response.";
  }
  return true;
}

}  // namespace verified_access
}  // namespace hwsec_test_utils
