| // 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 |