// 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 "cose/ocsp_verifier.h"

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

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "constants/status_codes.h"
#include "crypto/default/pem.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/validation_status.pb.h"
#include "testing/pem.h"
#include "tsp/verified_timestamp.h"

namespace credentio {
namespace {

using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::IsEmpty;
using ::testing::IsFalse;
using ::testing::SizeIs;

class MockCryptoReadHandler : public CryptoReadHandler {
 public:
  MOCK_METHOD(absl::StatusOr<std::unique_ptr<ParsedCertificates>>,
              ParseCertificatesDer,
              (absl::Span<const absl::string_view> certificates),
              (const, override));
  MOCK_METHOD(absl::StatusOr<VerifiedTimestamp>, VerifyTimestamp,
              (absl::string_view cms), (const, override));
  MOCK_METHOD(absl::StatusOr<OCSPRevocationStatus>, VerifyOcspResponse,
              (absl::string_view ocsp_response_der,
               absl::string_view certificate_der,
               absl::string_view issuer_certificate_der,
               absl::Time verify_time),
              (const, override));
  MOCK_METHOD(TrustEnvironment, trust_environment, (), (const, override));
};

// Matches validation status codes.
auto C2paStatusIs(auto status_code) {
  return ::testing::Property(&ValidationStatus::code,
                             Eq(absl::StrCat(status_code)));
}

absl::StatusOr<absl::Time> ParseTime(absl::string_view time_str) {
  absl::Time time;
  std::string err;
  if (!absl::ParseTime(absl::RFC3339_full, time_str, &time, &err)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Failed to parse time: ", err));
  }
  return time;
}

TEST(OcspVerifierTest, RecordSkippedOcspCheck) {
  ValidationStatusSet status_set;
  RecordSkippedOcspCheck(&status_set);

  EXPECT_THAT(status_set.failures(), IsEmpty());
  EXPECT_THAT(status_set.successes(), IsEmpty());
  EXPECT_THAT(status_set.informationals(),
              ElementsAre(C2paStatusIs(
                  InformationalStatusCode::kSigningCredentialOcspSkipped)));
}

TEST(OcspVerifierTest, SkippedWhenResponsesEmpty) {
  ValidationStatusSet status_set;
  std::vector<std::string> ocsp_responses = {};
  std::vector<std::string> trust_chain = {"fake_cert_1", "fake_cert_2"};
  absl::Time asserted_time = absl::Now();

  MockCryptoReadHandler mock_crypto_handler;
  EXPECT_CALL(mock_crypto_handler, VerifyOcspResponse).Times(0);
  OcspVerifier verifier(&mock_crypto_handler);

  EXPECT_TRUE(verifier.VerifyOcspResponses(ocsp_responses, trust_chain,
                                           asserted_time, &status_set));

  EXPECT_THAT(status_set.failures(), IsEmpty());
  EXPECT_THAT(status_set.successes(), IsEmpty());
  EXPECT_THAT(status_set.informationals(),
              ElementsAre(C2paStatusIs(
                  InformationalStatusCode::kSigningCredentialOcspSkipped)));
}

TEST(OcspVerifierTest, SkippedWhenNoValidResponses) {
  ValidationStatusSet status_set;
  // Valid check config but fake inputs that won't match/decode successfully.
  std::vector<std::string> ocsp_responses = {"invalid_ocsp_data"};
  std::vector<std::string> trust_chain = {"invalid_cert_1", "invalid_cert_2"};
  absl::Time asserted_time = absl::Now();

  MockCryptoReadHandler mock_crypto_handler;
  EXPECT_CALL(mock_crypto_handler, VerifyOcspResponse)
      .WillOnce(::testing::Return(absl::InvalidArgumentError("invalid ocsp")));
  OcspVerifier verifier(&mock_crypto_handler);

  EXPECT_TRUE(verifier.VerifyOcspResponses(ocsp_responses, trust_chain,
                                           asserted_time, &status_set));

  // Since CheckOCSP fails to identify revocation status, it will be neither
  // good nor revoked, hence recorded as skipped.
  EXPECT_THAT(status_set.failures(), IsEmpty());
  EXPECT_THAT(status_set.successes(), IsEmpty());
  EXPECT_THAT(status_set.informationals(),
              ElementsAre(C2paStatusIs(
                  InformationalStatusCode::kSigningCredentialOcspSkipped)));
}

// certs/claim_signer_ocsp_2010_2024.pem
static constexpr absl::string_view kSubjectCertPem =
    R"(-----BEGIN CERTIFICATE-----
MIIBVjCB/qADAgECAhEAqY+Ga0uKJc71iAGCQ2xmSTAKBggqhkjOPQQDAjAUMRIw
EAYDVQQDEwlSb290IENBIDEwHhcNMTAwMTAxMDAwMDAwWhcNMjQxMjMxMjM1OTU5
WjAcMRowGAYDVQQDExFDbGFpbSBTaWduZXIgT0NTUDBZMBMGByqGSM49AgEGCCqG
SM49AwEHA0IABIekbtQdrGd0nLIoGkyxOxUHVDrdf4kCsoG1oy8hKUp0JX1nN6I5
Uki0Rdnjjp0lkhRC7pS0ltq3RzYF2QLH9j2jKTAnMA4GA1UdDwEB/wQEAwIHgDAV
BgNVHSUEDjAMBgorBgEEAYPoXgIBMAoGCCqGSM49BAMCA0cAMEQCIEoOXctlLyTC
9ICtWt37D3UoLbtmGdPH/QKLuN5cEKmRAiABCe2qUdMzcrwR5rHJd2xQ8l4JZgv9
t7/qA0tV/kHm6g==
-----END CERTIFICATE-----
)";

// certs/root_ca1_cert.pem
static constexpr absl::string_view kIssuerCertPem =
    R"(-----BEGIN CERTIFICATE-----
MIIBaDCCAQ6gAwIBAgIQQjiBDyR9IFSiOk3YI9Vz6jAKBggqhkjOPQQDAjAUMRIw
EAYDVQQDEwlSb290IENBIDEwHhcNMDAwMTAxMDAwMDAwWhcNMjAwMTAxMDAwMDAw
WjAUMRIwEAYDVQQDEwlSb290IENBIDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AATGlEZ2h/3CeOl6anwJPvk9rY0SbQAUnM7ogiSCh2Xh8A4MA/ZFvFxLokfUS+Le
Rew96qN9o6jC7EXGs5Dlcql2o0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
BAUwAwEB/zAdBgNVHQ4EFgQUoD7enXLkSPQ4NFbWMsyPJw8CkREwCgYIKoZIzj0E
AwIDSAAwRQIgZHyZ6carq1CPrvQA87zDsfqVe1Hcy7/Hd2Pz8fTbn/YCIQC68wrO
LL8RURusZlo0c7KhG/TBTG368XayFcJbTq5piA==
-----END CERTIFICATE-----
)";

// ocsp/good_2012.pem
static constexpr absl::string_view kGoodOcspResponsePem =
    R"(-----BEGIN OCSP RESPONSE-----
MIICeAoBAKCCAnEwggJtBgkrBgEFBQcwAQEEggJeMIICWjCBpKEbMBkxFzAVBgNV
BAMTDk9DU1AgUmVzcG9uZGVyGA8yMDEyMDEwMTAwMDAwMFowdDByMEowCQYFKw4D
AhoFAAQUH/QKbQfkANfLUhHO1/Ux3C+InIMEFLEaFwXj/kcm0icZbAOdlyD4YMUx
AhEAqY+Ga0uKJc71iAGCQ2xmSYAAGA8yMDEyMDEwMTAwMDAwMFqgERgPMjAxMjEy
MzEyMzU5NTlaMAoGCCqGSM49BAMCA0cAMEQCIFBWX+xMGwGlswHlzGoxUqNe4MQS
6M6rsH3WVhB6V1XqAiAH7ENBzOuqkiwuyn/Ll22OehLDOwhGkcPj4ngBH981X6CC
AVowggFWMIIBUjCB+aADAgECAhEAylWc524QSfWaV4Y1C8VtVTAKBggqhkjOPQQD
AjAUMRIwEAYDVQQDEwlSb290IENBIDEwHhcNMTAwMTAxMDAwMDAwWhcNMjQxMjMx
MjM1OTU5WjAZMRcwFQYDVQQDEw5PQ1NQIFJlc3BvbmRlcjBZMBMGByqGSM49AgEG
CCqGSM49AwEHA0IABBxOD6IfWwY2vJ/dQfo3iquqL7jqrliO6KquLxGJYOuhmGiX
mgKhnXHv9fAF3xnb09BHZMqVvkW/Vjqx3VvWRjajJzAlMA4GA1UdDwEB/wQEAwIH
gDATBgNVHSUEDDAKBggrBgEFBQcDCTAKBggqhkjOPQQDAgNIADBFAiAk4CANeeK7
R5RQ+lgZkgiegSUaFu4pxHJzQ8yK2XnsqQIhAMevOsBvD9R6o5AmZJgn/dDsNwGQ
FuM38EKpIEjm+lH0
-----END OCSP RESPONSE-----
)";

// ocsp/revoked_2012.pem
static constexpr absl::string_view kRevokedOcspResponsePem =
    R"(-----BEGIN OCSP RESPONSE-----
MIICjQoBAKCCAoYwggKCBgkrBgEFBQcwAQEEggJzMIICbzCBt6EbMBkxFzAVBgNV
BAMTDk9DU1AgUmVzcG9uZGVyGA8yMDEyMDEwMTAwMDAwMFowgYYwgYMwSjAJBgUr
DgMCGgUABBQf9AptB+QA18tSEc7X9THcL4icgwQUsRoXBeP+RybSJxlsA52XIPhg
xTECEQCpj4ZrS4olzvWIAYJDbGZJoREYDzIwMTIwMTAxMDAwMDAwWhgPMjAxMjAx
MDEwMDAwMDBaoBEYDzIwMTIxMjMxMjM1OTU5WjAKBggqhkjOPQQDAgNJADBGAiEA
1N0hbCk0zfZUIWYqwwPmymq4l6/6379wQClNBvr+bWcCIQC8LPYY2wwrPGUa/LRu
hNmuv3wgUpapuqtrpRP9ool4S6CCAVowggFWMIIBUjCB+aADAgECAhEAylWc524Q
SfWaV4Y1C8VtVTAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlSb290IENBIDEwHhcN
MTAwMTAxMDAwMDAwWhcNMjQxMjMxMjM1OTU5WjAZMRcwFQYDVQQDEw5PQ1NQIFJl
c3BvbmRlcjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBxOD6IfWwY2vJ/dQfo3
iquqL7jqrliO6KquLxGJYOuhmGiXmgKhnXHv9fAF3xnb09BHZMqVvkW/Vjqx3VvW
RjajJzAlMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDCTAKBggq
hkjOPQQDAgNIADBFAiAk4CANeeK7R5RQ+lgZkgiegSUaFu4pxHJzQ8yK2XnsqQIh
AMevOsBvD9R6o5AmZJgn/dDsNwGQFuM38EKpIEjm+lH0
-----END OCSP RESPONSE-----
)";

TEST(OcspVerifierTest, MatchingGoodResponse) {
  auto subject_certs = LoadCertsFromPem(kSubjectCertPem);
  ABSL_ASSERT_OK(subject_certs);
  ASSERT_THAT(*subject_certs, SizeIs(1));

  auto issuer_certs = LoadCertsFromPem(kIssuerCertPem);
  ABSL_ASSERT_OK(issuer_certs);
  ASSERT_THAT(*issuer_certs, SizeIs(1));

  auto ocsp_response = LoadOcspResponseFromPem(kGoodOcspResponsePem);
  ABSL_ASSERT_OK(ocsp_response);

  ValidationStatusSet status_set;
  std::vector<std::string> ocsp_responses = {*ocsp_response};
  std::vector<std::string> trust_chain = {(*subject_certs)[0],
                                          (*issuer_certs)[0]};

  auto asserted_time = ParseTime("2012-06-01T00:00:00Z");
  ABSL_ASSERT_OK(asserted_time);

  MockCryptoReadHandler mock_crypto_handler;
  EXPECT_CALL(mock_crypto_handler,
              VerifyOcspResponse(*ocsp_response, (*subject_certs)[0],
                                 (*issuer_certs)[0], *asserted_time))
      .WillOnce(::testing::Return(OCSPRevocationStatus::kGood));
  OcspVerifier verifier(&mock_crypto_handler);

  EXPECT_TRUE(verifier.VerifyOcspResponses(ocsp_responses, trust_chain,
                                           *asserted_time, &status_set));

  EXPECT_THAT(status_set.failures(), IsEmpty());
  EXPECT_THAT(status_set.informationals(), IsEmpty());
  EXPECT_THAT(status_set.successes(),
              ElementsAre(C2paStatusIs(
                  SuccessStatusCode::kSigningCredentialOcspNotRevoked)));
}

TEST(OcspVerifierTest, MatchingRevokedResponse) {
  auto subject_certs = LoadCertsFromPem(kSubjectCertPem);
  ABSL_ASSERT_OK(subject_certs);
  ASSERT_THAT(*subject_certs, SizeIs(1));

  auto issuer_certs = LoadCertsFromPem(kIssuerCertPem);
  ABSL_ASSERT_OK(issuer_certs);
  ASSERT_THAT(*issuer_certs, SizeIs(1));

  auto ocsp_response = LoadOcspResponseFromPem(kRevokedOcspResponsePem);
  ABSL_ASSERT_OK(ocsp_response);

  ValidationStatusSet status_set;
  std::vector<std::string> ocsp_responses = {*ocsp_response};
  std::vector<std::string> trust_chain = {(*subject_certs)[0],
                                          (*issuer_certs)[0]};

  auto asserted_time = ParseTime("2012-06-01T00:00:00Z");
  ABSL_ASSERT_OK(asserted_time);

  MockCryptoReadHandler mock_crypto_handler;
  EXPECT_CALL(mock_crypto_handler,
              VerifyOcspResponse(*ocsp_response, (*subject_certs)[0],
                                 (*issuer_certs)[0], *asserted_time))
      .WillOnce(::testing::Return(OCSPRevocationStatus::kRevoked));
  OcspVerifier verifier(&mock_crypto_handler);

  EXPECT_THAT(verifier.VerifyOcspResponses(ocsp_responses, trust_chain,
                                           *asserted_time, &status_set),
              IsFalse());

  EXPECT_THAT(status_set.failures(),
              ElementsAre(C2paStatusIs(
                  FailureStatusCode::kSigningCredentialOcspRevoked)));
  EXPECT_THAT(status_set.informationals(), IsEmpty());
  EXPECT_THAT(status_set.successes(), IsEmpty());
}

TEST(OcspVerifierTest, MatchingRevokedResponseOnIntermediateCert) {
  auto subject_certs = LoadCertsFromPem(kSubjectCertPem);
  ABSL_ASSERT_OK(subject_certs);
  ASSERT_THAT(*subject_certs, SizeIs(1));

  auto issuer_certs = LoadCertsFromPem(kIssuerCertPem);
  ABSL_ASSERT_OK(issuer_certs);
  ASSERT_THAT(*issuer_certs, SizeIs(1));

  auto ocsp_response = LoadOcspResponseFromPem(kRevokedOcspResponsePem);
  ABSL_ASSERT_OK(ocsp_response);

  ValidationStatusSet status_set;
  std::vector<std::string> ocsp_responses = {*ocsp_response};
  // Insert a fake leaf cert so that subject_certs[0] is considered an
  // intermediate cert.
  std::vector<std::string> trust_chain = {"fake_leaf_cert", (*subject_certs)[0],
                                          (*issuer_certs)[0]};

  auto asserted_time = ParseTime("2012-06-01T00:00:00Z");
  ABSL_ASSERT_OK(asserted_time);

  MockCryptoReadHandler mock_crypto_handler;
  EXPECT_CALL(mock_crypto_handler,
              VerifyOcspResponse(*ocsp_response, "fake_leaf_cert",
                                 (*subject_certs)[0], *asserted_time))
      .WillOnce(::testing::Return(absl::InvalidArgumentError("no match")));
  EXPECT_CALL(mock_crypto_handler,
              VerifyOcspResponse(*ocsp_response, (*subject_certs)[0],
                                 (*issuer_certs)[0], *asserted_time))
      .WillOnce(::testing::Return(OCSPRevocationStatus::kRevoked));
  OcspVerifier verifier(&mock_crypto_handler);

  EXPECT_THAT(verifier.VerifyOcspResponses(ocsp_responses, trust_chain,
                                           *asserted_time, &status_set),
              IsFalse());

  EXPECT_THAT(status_set.failures(),
              ElementsAre(C2paStatusIs(
                  FailureStatusCode::kSigningCredentialUntrusted)));
  EXPECT_THAT(status_set.informationals(), IsEmpty());
  EXPECT_THAT(status_set.successes(), IsEmpty());
}

TEST(OcspVerifierTest, MatchingGoodResponseOnIntermediateCert) {
  auto subject_certs = LoadCertsFromPem(kSubjectCertPem);
  ABSL_ASSERT_OK(subject_certs);
  ASSERT_THAT(*subject_certs, SizeIs(1));

  auto issuer_certs = LoadCertsFromPem(kIssuerCertPem);
  ABSL_ASSERT_OK(issuer_certs);
  ASSERT_THAT(*issuer_certs, SizeIs(1));

  auto ocsp_response = LoadOcspResponseFromPem(kGoodOcspResponsePem);
  ABSL_ASSERT_OK(ocsp_response);

  ValidationStatusSet status_set;
  std::vector<std::string> ocsp_responses = {*ocsp_response};
  // Insert a fake leaf cert so that subject_certs[0] is considered an
  // intermediate cert.
  std::vector<std::string> trust_chain = {"fake_leaf_cert", (*subject_certs)[0],
                                          (*issuer_certs)[0]};

  auto asserted_time = ParseTime("2012-06-01T00:00:00Z");
  ABSL_ASSERT_OK(asserted_time);

  MockCryptoReadHandler mock_crypto_handler;
  EXPECT_CALL(mock_crypto_handler,
              VerifyOcspResponse(*ocsp_response, "fake_leaf_cert",
                                 (*subject_certs)[0], *asserted_time))
      .WillOnce(::testing::Return(absl::InvalidArgumentError("no match")));
  EXPECT_CALL(mock_crypto_handler,
              VerifyOcspResponse(*ocsp_response, (*subject_certs)[0],
                                 (*issuer_certs)[0], *asserted_time))
      .WillOnce(::testing::Return(OCSPRevocationStatus::kGood));
  OcspVerifier verifier(&mock_crypto_handler);

  EXPECT_TRUE(verifier.VerifyOcspResponses(ocsp_responses, trust_chain,
                                           *asserted_time, &status_set));

  EXPECT_THAT(status_set.failures(), IsEmpty());
  EXPECT_THAT(status_set.informationals(),
              ElementsAre(C2paStatusIs(
                  InformationalStatusCode::kSigningCredentialOcspSkipped)));
  EXPECT_THAT(status_set.successes(), IsEmpty());
}

}  // namespace
}  // namespace credentio
