// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "crypto/default/cms/verify_signature.h"

#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "crypto/default/cms/certificates.h"
#include "crypto/default/cms/cms_error_code.h"
#include "crypto/default/cms/cms_parser.h"
#include "crypto/default/cms/cms_test_helper.h"
#include "crypto/default/cms/oids.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "openssl/base.h"
#include "openssl/bytestring.h"
#include "openssl/mem.h"
#include "openssl/nid.h"
#include "openssl/obj.h"
#include "openssl/obj_mac.h"
#include "openssl/safestack.h"
#include "openssl/stack.h"

namespace credentio_cms {
namespace {

using ::absl_testing::IsOk;
using ::absl_testing::StatusIs;

ByteString ByteStringFromString(const std::string& value) {
  ByteString bs;
  CBS_init(bs.cbs_ptr(), reinterpret_cast<const unsigned char*>(value.data()),
           value.length());
  return bs;
}

std::string ByteStringToString(const ByteString& bs) {
  return std::string(reinterpret_cast<const char*>(CBS_data(bs.cbs_ptr())),
                     CBS_len(bs.cbs_ptr()));
}

class VerifySignatureTest : public ::testing::Test {
 protected:
  void ParseOpaqueMessage(const char* filename) {
    std::string message = GetFileContents(filename);
    cms_object_der_ = GetCms(message);
    std::string error_message;
    EXPECT_EQ(ErrorCode::OK,
              ParseCms(cms_object_der_.data(), cms_object_der_.length(), &cms_,
                       &error_message))
        << "Failed to parse: " << filename << " error: " << error_message;
  }

  void ParseMessage(const char* filename) {
    std::string message = GetFileContents(filename);
    // The first mime part in the message, in the tests this is the clear text.
    first_part_ = GetFirstMimePart(message);
    cms_object_der_ = GetCms(message);
    std::string error_message;
    EXPECT_EQ(ErrorCode::OK,
              ParseCms(cms_object_der_.data(), cms_object_der_.length(), &cms_,
                       &error_message))
        << error_message;
  }

  // Pick the first certificate matching the signer restrictions, or null if
  // none was found.
  X509* GetFirstMatchingCert(const Content& content, const SignerInfo& signer) {
    certificate_stack_.reset(GetAllCertificates(content));
    if (certificate_stack_ == nullptr) {
      return nullptr;
    }
    std::vector<X509*> matches =
        GetSignerCertificates(certificate_stack_.get(), signer);
    if (matches.empty()) {
      return nullptr;
    }
    return matches[0];
  }

  std::string first_part_;
  std::string cms_object_der_;
  Content cms_;
  bssl::UniquePtr<STACK_OF(X509)> certificate_stack_;
};

class VerifyOpaqueSignaturesTest
    : public VerifySignatureTest,
      public ::testing::WithParamInterface<const char*> {};

TEST_P(VerifyOpaqueSignaturesTest, CheckSignature) {
  ParseOpaqueMessage(GetParam());
  ASSERT_EQ(1, cms_.signers.size());
  ASSERT_EQ(1, cms_.content.size());

  for (const auto& signer : cms_.signers) {
    X509* certificate = GetFirstMatchingCert(cms_, signer);
    ASSERT_FALSE(certificate == nullptr)
        << "Failed to get the certificate for: " << GetParam()
        << " and Issuer: " << CBSToName(signer.issuer_name);
    auto status = VerifySignature(cms_, signer, cms_.content, *certificate);
    EXPECT_TRUE(status.ok()) << status.status();

    // Sanity check: change the first bit and check that the signature fails.
    std::string data = ByteStringToString(cms_.content[0]);
    data[0] ^= 0x80;
    ByteString modified = ByteStringFromString(data);
    EXPECT_FALSE(VerifySignature(cms_, signer, {modified}, *certificate).ok());
  }
}

INSTANTIATE_TEST_SUITE_P(EmbeddedContent, VerifyOpaqueSignaturesTest,
                         testing::Values("signed-openssl-opaque.msg",
                                         "signed-openssl-ecdsa.msg"));

class VerifyDetachedSignaturesTest
    : public VerifySignatureTest,
      public ::testing::WithParamInterface<const char*> {};

TEST_P(VerifyDetachedSignaturesTest, CheckSignatureWithExternalContent) {
  ParseMessage(GetParam());
  ASSERT_EQ(1, cms_.signers.size());
  EXPECT_EQ(0, cms_.content.size());
  ByteString data = ByteStringFromString(first_part_);

  for (const auto& signer : cms_.signers) {
    X509* certificate = GetFirstMatchingCert(cms_, signer);
    ASSERT_FALSE(certificate == nullptr);
    auto status = VerifySignature(cms_, signer, {data}, *certificate);
    EXPECT_TRUE(status.ok()) << status.status();
  }
}

INSTANTIATE_TEST_SUITE_P(ExternalContent, VerifyDetachedSignaturesTest,
                         testing::Values("signed-openssl-detached.msg",
                                         "signed-outlook-mac-2011.msg",
                                         "signed-thunderbird.msg",
                                         "signed-openssl-pss.msg",
                                         "signed-openssl-sha256.msg"));

class VerifyFailedSignaturesTest
    : public VerifySignatureTest,
      public ::testing::WithParamInterface<const char*> {};

TEST_P(VerifyFailedSignaturesTest, CheckSignatureWithExternalContent) {
  ParseMessage(GetParam());
  ASSERT_EQ(1, cms_.signers.size());
  EXPECT_EQ(0, cms_.content.size());
  ByteString data = ByteStringFromString(first_part_);

  for (const auto& signer : cms_.signers) {
    X509* certificate = GetFirstMatchingCert(cms_, signer);
    ASSERT_FALSE(certificate == nullptr);
    auto status = VerifySignature(cms_, signer, {data}, *certificate);
    EXPECT_FALSE(status.ok()) << status.status();
  }
}
INSTANTIATE_TEST_SUITE_P(
    ExternalContent, VerifyFailedSignaturesTest,
    testing::Values("signed-type-mismatch.msg",
                    "signed-unknown-hash-algorithm.msg",
                    "signed-unknown-signature-algorithm.msg"));

TEST_F(VerifySignatureTest, MissingSignedAttributes) {
  // The signed attributes are needed if the the envelope content type is not
  // data.
  ParseMessage("signed-openssl-detached.msg");
  auto& signer = cms_.signers[0];
  // Clear the signed attributes.
  CBS_init(signer.raw_signed_attributes.cbs_ptr(), nullptr, 0);
  CBS_init(cms_.content_type.cbs_ptr(), kSignedDataOid, sizeof(kSignedDataOid));

  ByteString data = ByteStringFromString(first_part_);
  X509* certificate = GetFirstMatchingCert(cms_, signer);
  ASSERT_FALSE(certificate == nullptr);
  auto status = VerifySignature(cms_, signer, {data}, *certificate);
  EXPECT_FALSE(status.ok()) << status.status();
}

TEST_F(VerifySignatureTest, MissingSignerDigest) {
  ParseMessage("signed-openssl-detached.msg");
  auto& signer = cms_.signers[0];
  // Clear the signed message digest attribute.
  CBS_init(signer.message_digest.cbs_ptr(), nullptr, 0);

  ByteString data = ByteStringFromString(first_part_);
  X509* certificate = GetFirstMatchingCert(cms_, signer);
  ASSERT_FALSE(certificate == nullptr);
  auto status = VerifySignature(cms_, signer, {data}, *certificate);
  EXPECT_FALSE(status.ok()) << status.status();
}

TEST_F(VerifySignatureTest, MissingContentTypeSigned) {
  ParseMessage("signed-openssl-detached.msg");
  auto& signer = cms_.signers[0];
  // Clear the signed content_type_signed attribute.
  CBS_init(signer.content_type_signed.cbs_ptr(), nullptr, 0);

  ByteString data = ByteStringFromString(first_part_);
  X509* certificate = GetFirstMatchingCert(cms_, signer);
  ASSERT_FALSE(certificate == nullptr);
  auto status = VerifySignature(cms_, signer, {data}, *certificate);
  EXPECT_FALSE(status.ok()) << status.status();
}

TEST_F(VerifySignatureTest, CertificateWithBrokenPubKey) {
  ParseMessage("signed-openssl-detached.msg");
  ByteString data = ByteStringFromString(first_part_);
  // user1_bad_public_key has a public key with an unknown OID.
  bssl::UniquePtr<X509> certificate(
      PemToCertificate(GetFileContents("user1_bad_public_key.pem")));
  auto status = VerifySignature(cms_, cms_.signers[0], {data}, *certificate);
  EXPECT_FALSE(status.ok()) << status.status();
}

TEST_F(VerifySignatureTest, BadSignatureDigestAlgorithm) {
  ParseMessage("signed-openssl-detached.msg");
  auto& signer = cms_.signers[0];
  // Use an OID known to OpenSSL but that is not a valid hash or signature
  // algorithm with an implied hash function.
  // 1.2.840.113549.3.7  DES-EDE3-CBC
  auto oid = NidToDerString(NID_des_ede3_cbc);
  signer.signature_algorithm.algorithm_oid = ByteStringFromString(oid);
  signer.digest_algorithm.algorithm_oid = ByteStringFromString(oid);

  ByteString data = ByteStringFromString(first_part_);
  X509* certificate = GetFirstMatchingCert(cms_, signer);
  ASSERT_FALSE(certificate == nullptr);
  auto status = VerifySignature(cms_, signer, {data}, *certificate);
  EXPECT_FALSE(status.ok()) << status.status();
}

TEST_F(VerifySignatureTest, BadHashDigestAlgorithm) {
  ParseMessage("signed-openssl-sha256.msg");
  auto& signer = cms_.signers[0];
  // Use a signature OID that provides an explicit hashing algorithm.
  auto sig_oid = NidToDerString(NID_sha256WithRSAEncryption);
  signer.signature_algorithm.algorithm_oid = ByteStringFromString(sig_oid);

  ByteString data = ByteStringFromString(first_part_);
  X509* certificate = GetFirstMatchingCert(cms_, signer);
  ASSERT_FALSE(certificate == nullptr);
  auto status = VerifySignature(cms_, signer, {data}, *certificate);
  // Make sure that the signature algorithm is correct.
  EXPECT_TRUE(status.ok()) << status.status();

  // Use an OID known to OpenSSL but that is not a valid hash algorithm.
  // 1.2.840.113549.3.7  DES-EDE3-CBC
  auto digest_oid = NidToDerString(NID_des_ede3_cbc);
  signer.digest_algorithm.algorithm_oid = ByteStringFromString(digest_oid);
  status = VerifySignature(cms_, signer, {data}, *certificate);
  EXPECT_FALSE(status.ok()) << status.status();
}

TEST_F(VerifySignatureTest, WrongSignedHashLength) {
  ParseMessage("signed-openssl-sha256.msg");
  auto& signer = cms_.signers[0];
  // Shrink the digest length by one.
  CBS_init(signer.message_digest.cbs_ptr(),
           CBS_data(signer.message_digest.cbs_ptr()),
           CBS_len(signer.message_digest.cbs_ptr()) - 1);
  ByteString data = ByteStringFromString(first_part_);
  X509* certificate = GetFirstMatchingCert(cms_, signer);
  ASSERT_FALSE(certificate == nullptr);
  auto status = VerifySignature(cms_, signer, {data}, *certificate);
  EXPECT_FALSE(status.ok()) << status.status();
}

TEST_F(VerifySignatureTest, MissingPSSParameters) {
  ParseMessage("signed-openssl-pss.msg");
  auto& signer = cms_.signers[0];
  CBS_init(signer.signature_algorithm.parameter.cbs_ptr(), nullptr, 0);
  ByteString data = ByteStringFromString(first_part_);
  X509* certificate = GetFirstMatchingCert(cms_, signer);
  ASSERT_FALSE(certificate == nullptr);
  auto status = VerifySignature(cms_, signer, {data}, *certificate);
  EXPECT_FALSE(status.ok()) << status.status();
}

TEST_F(VerifySignatureTest, CheckSignatureInfo) {
  ParseMessage("signed-openssl-pss.msg");
  auto& signer = cms_.signers[0];
  ByteString data = ByteStringFromString(first_part_);
  X509* certificate = GetFirstMatchingCert(cms_, signer);
  ASSERT_FALSE(certificate == nullptr);
  auto status = VerifySignature(cms_, signer, {data}, *certificate);
  ASSERT_TRUE(status.ok()) << status.status();
  EXPECT_EQ(NID_rsassaPss, status.value().signature_algorithm_id);
  EXPECT_EQ(NID_sha256, status.value().digest_algorithm_nid);
}

TEST_F(VerifySignatureTest, MismatchedHashDigestAlgorithmEcdsa) {
  ParseOpaqueMessage("signed-openssl-ecdsa.msg");
  auto& signer = cms_.signers[0];
  // Use a signature OID that provides an explicit hashing algorithm and use the
  // right hash algorithm to make sure the test case is valid.
  auto sig_oid = NidToDerString(NID_ecdsa_with_SHA256);
  signer.signature_algorithm.algorithm_oid = ByteStringFromString(sig_oid);
  auto good_digest_oid = NidToDerString(NID_sha256);
  signer.digest_algorithm.algorithm_oid = ByteStringFromString(good_digest_oid);

  ByteString data = ByteStringFromString(first_part_);
  X509* certificate = GetFirstMatchingCert(cms_, signer);
  ASSERT_FALSE(certificate == nullptr);
  // Make sure signature algorithm is correct.
  EXPECT_THAT(VerifySignature(cms_, signer, cms_.content, *certificate),
              IsOk());

  // Set hash algorithm to a supported value that is different from the one
  // implied by the signature algorithm.
  auto bad_digest_oid = NidToDerString(NID_sha384);
  signer.digest_algorithm.algorithm_oid = ByteStringFromString(bad_digest_oid);
  EXPECT_THAT(
      VerifySignature(cms_, signer, {data}, *certificate),
      StatusIs(
          absl::StatusCode::kInvalidArgument,
          R"(The digest algorithm does not match the value derived from the signature algorithm: digest_nid=673, signature_digest_nid=672)"));
}

}  // namespace
}  // namespace credentio_cms
