// 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/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
