blob: 9e27c891a9a551fab0b35ead6fbb918a55c70345 [file] [edit]
// 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/verifier.h"
#include <memory>
#include <optional>
#include <utility>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "constants/labels.h"
#include "constants/status_codes.h"
#include "cose/cose_sign1.h"
#include "cose/sig_structure.h"
#include "cose/validation_status_util.h"
#include "crypto/default/hasher.h"
#include "crypto/hash.h"
#include "google/protobuf/timestamp.pb.h"
#include "proto/cose_verification_result.pb.h"
#include "proto/signature_info.pb.h"
#include "proto/validation_status.pb.h"
namespace credentio {
namespace {
class CoseVerifierImpl : public CoseVerifier {
public:
explicit CoseVerifierImpl(CoseVerifierOptions options)
: options_(std::move(options)) {}
CoseVerificationResult Verify(absl::string_view cose_signature,
absl::string_view data) const override {
CoseVerificationResult result;
ValidationStatusSet* status_set = result.mutable_validation_status();
absl::StatusOr<CoseSign1TaggedStructure> cose_sign1_struct =
DecodeCoseSign1TaggedStructure(cose_signature);
if (!cose_sign1_struct.ok()) {
RecordStatus(status_set, FailureStatusCode::kSigningCredentialInvalid,
{.url = kClaimSignatureLabel,
.explanation = cose_sign1_struct.status().ToString()});
return result;
}
auto cose_sign1_verifier = CoseSign1Verifier::Create(
options_.crypto_read_handler.get(), &DefaultHashCheckerFactory(),
options_.clock,
CoseSign1Verifier::Options{
.check_ocsp_responses = options_.revocation_checks ==
CoseVerifierRevocationChecks::kEnabled,
.verify_signature = options_.signature_checks ==
CoseVerifierSignatureChecks::kEnabled,
});
std::optional<SignatureInfo> signature_info = cose_sign1_verifier->Verify(
*std::move(cose_sign1_struct), data, status_set);
if (!signature_info.has_value()) {
// Failure has already been recorded to the tracker by CoseSign1::Verify.
return result;
}
*result.mutable_signature_info() = *std::move(signature_info);
return result;
}
private:
const CoseVerifierOptions options_;
};
} // namespace
std::unique_ptr<CoseVerifier> CreateCoseVerifier(CoseVerifierOptions options) {
CHECK(options.crypto_read_handler);
return std::make_unique<CoseVerifierImpl>(std::move(options));
}
} // namespace credentio