| // 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 "assertion/hashed_uri_validator.h" |
| |
| #include <memory> |
| #include <optional> |
| #include <string> |
| |
| #include "absl/status/statusor.h" |
| #include "absl/strings/string_view.h" |
| #include "constants/status_codes.h" |
| #include "crypto/algorithms.h" |
| #include "crypto/hash.h" |
| #include "jumbf/uri.h" |
| #include "jumbf/utils.h" |
| #include "proto/hashed_uri.pb.h" |
| #include "validator/tracker.h" |
| |
| namespace credentio { |
| |
| std::optional<std::string> HashedUriValidator::Validate( |
| const HashedUri& hashed_uri, absl::string_view assertion_url, |
| ValidationTracker& validation_tracker) const { |
| auto record_failure = [&](FailureStatusCode code, |
| absl::string_view explanation = |
| "") -> std::optional<std::string> { |
| validation_tracker.RecordFailure( |
| code, {.url = assertion_url, .explanation = explanation}); |
| return std::nullopt; |
| }; |
| |
| // Check the uri. |
| auto path = jumbf::UriResolver::GetAbsolutePathFromUri(hashed_uri.url(), |
| manifest_path_); |
| if (!path.ok()) { |
| return record_failure(codes_.missing, path.status().message()); |
| } |
| auto box = uri_resolver_.ResolvePath(*path); |
| if (!box.ok()) { |
| return record_failure(codes_.missing, box.status().message()); |
| } |
| |
| // Check the algorithm. |
| absl::string_view alg_name = |
| hashed_uri.algorithm().empty() ? alg_ : hashed_uri.algorithm(); |
| auto algorithm = ParseHashAlgorithm(alg_name); |
| if (!algorithm.ok()) { |
| return record_failure(FailureStatusCode::kAlgorithmUnsupported); |
| } |
| auto checker = hash_checker_factory_.Create(*algorithm); |
| if (!checker.ok()) { |
| return record_failure(FailureStatusCode::kAlgorithmUnsupported); |
| } |
| |
| // Check the hash. |
| auto box_bytes = jumbf::StripBoxHeaders((*box)->raw_bytes); |
| if (!box_bytes.ok()) { |
| return record_failure(codes_.mismatch); |
| } |
| (*checker)->Update(*box_bytes); |
| if (!(*checker)->Check(hashed_uri.hash())) { |
| return record_failure(codes_.mismatch); |
| } |
| |
| return *path; |
| } |
| |
| } // namespace credentio |