diff --git a/source/src/templates.cpp b/source/src/templates.cpp index e4af907..3691409 100644 --- a/source/src/templates.cpp +++ b/source/src/templates.cpp @@ -243,9 +243,18 @@ if (metadata.contains("version")) { registry_version = metadata["version"].get(); } - } - if (registry_metadata.contains("hash")) { - registry_hash = registry_metadata["hash"].get(); + // REQUIRED: templateXXHash64 - the XXHash64 of extracted contents + if (metadata.contains("templateXXHash64")) { + registry_hash = metadata["templateXXHash64"].get(); + debug << "Found templateXXHash64 in metadata: " << registry_hash << std::endl; + } else { + // templateXXHash64 is required for security + error << "Template '" << template_name << "' from registry '" << mRegistry.name + << "' does not provide templateXXHash64 for integrity verification." << std::endl; + error << "This template cannot be downloaded for security reasons." << std::endl; + error << "Please contact the registry administrator to update the template metadata." << std::endl; + return template_info(); + } } // Check if we have a cached version @@ -307,36 +316,38 @@ uint64_t actual_hash = hash_directory_recursive(template_cache_dir.string()); // Verify the extracted template hash matches what registry claimed - if (!registry_hash.empty()) { - // Convert registry hash string to uint64_t for comparison - uint64_t expected_hash = 0; - try { - expected_hash = std::stoull(registry_hash); - } catch (const std::exception& e) { - error << "Invalid hash format from registry: " << registry_hash << std::endl; - std::filesystem::remove_all(template_cache_dir); - return template_info(); - } - - // Compare hashes - if (actual_hash != expected_hash) { - error << "Template hash verification failed!" << std::endl; - error << "Expected hash: " << expected_hash << std::endl; - error << "Actual hash: " << actual_hash << std::endl; - error << "The downloaded template '" << template_name << "' may be corrupted or tampered with." << std::endl; - - // Remove the corrupted template - std::filesystem::remove_all(template_cache_dir); - return template_info(); - } - - debug << "Template hash verified successfully: " << actual_hash << std::endl; - } else { - warning << "Registry did not provide hash for template '" << template_name << "' - calculating hash for future verification" << std::endl; - // Use the calculated hash for future comparisons - registry_hash = std::to_string(actual_hash); + // templateXXHash64 is required, so registry_hash should always be set here + if (registry_hash.empty()) { + // This shouldn't happen as we check for it above, but handle it just in case + error << "Internal error: templateXXHash64 was not properly set" << std::endl; + std::filesystem::remove_all(template_cache_dir); + return template_info(); } + // Convert registry hash string to uint64_t for comparison + uint64_t expected_hash = 0; + try { + expected_hash = std::stoull(registry_hash); + } catch (const std::exception& e) { + error << "Invalid templateXXHash64 format from registry: " << registry_hash << std::endl; + std::filesystem::remove_all(template_cache_dir); + return template_info(); + } + + // Compare hashes + if (actual_hash != expected_hash) { + error << "Template hash verification failed!" << std::endl; + error << "Expected hash (templateXXHash64): " << expected_hash << std::endl; + error << "Actual hash: " << actual_hash << std::endl; + error << "The downloaded template '" << template_name << "' may be corrupted or tampered with." << std::endl; + + // Remove the corrupted template + std::filesystem::remove_all(template_cache_dir); + return template_info(); + } + + info << "Template hash verified successfully (templateXXHash64): " << actual_hash << std::endl; + // Generate .template_info.env if it doesn't exist std::filesystem::path template_info_env_path = template_cache_dir / "config" / filenames::template_info_env; if (!std::filesystem::exists(template_info_env_path)) {