| // 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. |
| // |
| |
| #ifndef THIRD_PARTY_CREDENTIO_CRYPTO_CRYPTO_READ_HANDLER_H_ |
| #define THIRD_PARTY_CREDENTIO_CRYPTO_CRYPTO_READ_HANDLER_H_ |
| |
| #include <cstddef> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/string_view.h" |
| #include "absl/time/time.h" |
| #include "absl/types/span.h" |
| #include "crypto/algorithms.h" |
| #include "crypto/timestamp_read_handler.h" |
| |
| namespace credentio { |
| |
| // A parsed public-key certificate with optional supporting intermediate certs. |
| class ParsedCertificates { |
| public: |
| virtual ~ParsedCertificates() = default; |
| |
| // Verifies that `signature` applies to `data`, using the public key from the |
| // leaf certificate. This function can be used for both claim and OCSP |
| // response signatures. Performs no trust checks. |
| // |
| // Returns: |
| // - INVALID_ARGUMENT if the signature is invalid. |
| virtual absl::Status VerifySignature(absl::string_view signature, |
| absl::string_view data, |
| SigningAlgorithm algorithm) const = 0; |
| |
| // Verifies the trustworthiness of the leaf certificate for claim signing, by |
| // finding an ordered chain of valid certificates to a trusted root, |
| // making use of the provided intermediate certificates as needed. All |
| // certificate checks are performed in accordance with |
| // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_general_requirements, |
| // and validity period checks are performed based on the provided time. |
| // |
| // Returns: |
| // - UNAUTHENTICATED if the certificate cannot be trusted. |
| // - OUT_OF_RANGE if `content_time` is outside the validity period of a |
| // certificate. |
| // - INVALID_ARGUMENT if a certificate is invalid. |
| // - UNAVAILABLE if the root trust list cannot be accessed (only possible on |
| // platforms where it is not built into the binary). |
| // - The verified trust chain from leaf to root (including the relevant |
| // trust anchor's cert) if the verification is successful. |
| virtual absl::StatusOr<std::vector<std::string>> VerifyClaimSignerTrust( |
| absl::Time content_time) const = 0; |
| |
| // Returns the number of certificates in the chain. Index 0 is the leaf |
| // certificate, but the order of the other certificates is not guaranteed |
| // and not all of them are necessarily part of the chain to a trust anchor |
| // that a successful call to VerifyClaimSignerTrust finds. There is always at |
| // least 1 certificate. |
| virtual size_t GetCertificateCount() const = 0; |
| |
| // Returns the distinguished name of the subject of the certificate |
| // (RFC 2253 format). Index 0 represents the leaf certificate. |
| virtual absl::StatusOr<std::string> GetSubject(size_t index) const = 0; |
| // Returns the distinguished name of the issuer of the certificate |
| // (RFC 2253 format). |
| virtual absl::StatusOr<std::string> GetIssuer(size_t index) const = 0; |
| |
| // Returns the certificates's start time (notBefore). |
| virtual absl::StatusOr<absl::Time> GetStartTime(size_t index) const = 0; |
| |
| // Returns the certificate's end time (notAfter) |
| virtual absl::StatusOr<absl::Time> GetEndTime(size_t index) const = 0; |
| // Returns the certificate's serial number as a lowercase hex string. |
| virtual absl::StatusOr<std::string> GetSerialNumberHex( |
| size_t index) const = 0; |
| |
| // Returns the certificate's C2PA assurance level as a string (e.g., |
| // "1.3.6.1.4.1.62558.3.10"), if it is present and can be parsed. |
| // This is only relevant for the leaf certificate (index 0). |
| virtual absl::StatusOr<std::string> GetAssuranceLevel(size_t index) const = 0; |
| |
| // Returns the certificate's C2PA conforming product ID. |
| // This is only relevant for the leaf certificate (index 0). |
| virtual absl::StatusOr<std::string> GetConformingProductId( |
| size_t index) const = 0; |
| }; |
| |
| // Represents the certificate revocation status returned by the OCSP |
| // responder, as defined in RFC 6960 (Section 2.2). |
| enum class OCSPRevocationStatus { |
| kUnknown, // The responder does not know the status of the certificate. |
| kGood, // The certificate is not revoked (valid). |
| kRevoked, // The certificate has been revoked. |
| }; |
| |
| // Encapsulates the crypto operation involved in claim verification. |
| class CryptoReadHandler : public TimestampReadHandler { |
| public: |
| enum class TrustEnvironment { |
| kUnspecified, |
| // Trust any certificates, i.e., skip claim signer and timestamp trust |
| // checks. |
| kAny, |
| // Trust dev certificates only. |
| kDevOnly, |
| // Trust qual certificates for signers and prod certificates for timestamps. |
| kQualOnly, |
| // Trust qual and prod certificates. |
| kQualAndProd, |
| // Trust prod certificates only. |
| kProd, |
| }; |
| |
| ~CryptoReadHandler() override = default; |
| |
| // Parses a set of DER-encoded certificates, the first of which is the |
| // leaf certificate. |
| virtual absl::StatusOr<std::unique_ptr<ParsedCertificates>> |
| ParseCertificatesDer( |
| absl::Span<const absl::string_view> certificates) const = 0; |
| |
| // Verifies the signature and validity of the DER-encoded OCSP response |
| // against the provided issuer certificate (`issuer_certificate_der`) or |
| // an authorized responder, and returns the revocation status of the target |
| // certificate (`certificate_der`) at the specified verification time |
| // (`verify_time`). |
| // |
| // The verification process ensures that the OCSP response is correctly signed |
| // by the issuer or a delegated responder, conforms to RFC 6960 requirements, |
| // matches the target certificate, and is valid at `verify_time`. |
| // |
| // Arguments: |
| // ocsp_response_der: The DER-encoded OCSP response. |
| // certificate_der: The DER-encoded X.509 certificate whose revocation |
| // status is being checked. |
| // issuer_certificate_der: The DER-encoded X.509 certificate of the issuer |
| // that signed `certificate_der`. |
| // verify_time: The time at which the OCSP response validity and revocation |
| // status are evaluated. |
| // |
| // Returns: |
| // - INVALID_ARGUMENT if `certificate_der`, `issuer_certificate_der`, or the |
| // OCSP response is malformed or invalid. |
| // - UNAUTHENTICATED if the OCSP response signature fails verification or |
| // if no matching response is found for `certificate_der`. |
| // - OUT_OF_RANGE if `verify_time` is outside the valid time window of the |
| // OCSP response (e.g., based on `thisUpdate` and `nextUpdate`). |
| // - The verified `OCSPRevocationStatus` (kGood, kRevoked, or kUnknown) if |
| // verification is successful. |
| virtual 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 = 0; |
| |
| // Returns the trust environment of this handler. |
| virtual TrustEnvironment trust_environment() const = 0; |
| }; |
| |
| bool AbslParseFlag(absl::string_view text, |
| CryptoReadHandler::TrustEnvironment* trust, |
| std::string* error); |
| |
| std::string AbslUnparseFlag(CryptoReadHandler::TrustEnvironment trust); |
| |
| } // namespace credentio |
| |
| #endif // THIRD_PARTY_CREDENTIO_CRYPTO_CRYPTO_READ_HANDLER_H_ |