From 0ecb7271aefc303a5fbcdcef4f131a179c810069 Mon Sep 17 00:00:00 2001 From: AssemblyJohn Date: Fri, 26 Apr 2024 15:05:19 +0300 Subject: [PATCH] Fixes for OCSP data cleanup and test updates Signed-off-by: AssemblyJohn --- lib/evse_security/evse_security.cpp | 73 +++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/lib/evse_security/evse_security.cpp b/lib/evse_security/evse_security.cpp index dcb5b7f..fe6e6fc 100644 --- a/lib/evse_security/evse_security.cpp +++ b/lib/evse_security/evse_security.cpp @@ -1326,8 +1326,10 @@ std::string EvseSecurity::get_verify_file(CaCertificateType certificate_type) { << this->ca_bundle_path_map.at(certificate_type) << " with error: " << e.what(); } - throw NoCertificateFound("Could not find any CA certificate for: " + - conversions::ca_certificate_type_to_string(certificate_type)); + EVLOG_error << "Could not find any CA certificate for: " + << conversions::ca_certificate_type_to_string(certificate_type); + + return {}; } int EvseSecurity::get_leaf_expiry_days_count(LeafCertificateType certificate_type) { @@ -1611,7 +1613,7 @@ void EvseSecurity::garbage_collect() { read_hash == ocsp_hash) { auto oscp_data_path = hash_entry.path(); - oscp_data_path.replace_extension(CERT_HASH_EXTENSION); + oscp_data_path.replace_extension(DER_EXTENSION); invalid_certificate_files.emplace(hash_entry.path()); invalid_certificate_files.emplace(oscp_data_path); @@ -1654,7 +1656,7 @@ void EvseSecurity::garbage_collect() { for (const auto& expired_certificate_file : invalid_certificate_files) { if (filesystem_utils::delete_file(expired_certificate_file)) - EVLOG_debug << "Deleted expired certificate file: " << expired_certificate_file; + EVLOG_info << "Deleted expired certificate file: " << expired_certificate_file; else EVLOG_warning << "Error deleting expired certificate file: " << expired_certificate_file; } @@ -1710,6 +1712,69 @@ void EvseSecurity::garbage_collect() { ++it; } } + + std::set invalid_ocsp_files; + + // Delete all non-owned OCSP data + for (const auto& leaf_certificate_path : + {directories.secc_leaf_cert_directory, directories.csms_leaf_cert_directory}) { + try { + bool secc = (leaf_certificate_path == directories.secc_leaf_cert_directory); + bool csms = (leaf_certificate_path == directories.csms_leaf_cert_directory) || + (directories.csms_leaf_cert_directory == directories.secc_leaf_cert_directory); + + CaCertificateType load; + + if (secc) + load = CaCertificateType::V2G; + else if (csms) + load = CaCertificateType::CSMS; + + // Also load the roots since we need to build the hierarchy for correct certificate hashes + X509CertificateBundle root_bundle(ca_bundle_path_map[load], EncodingFormat::PEM); + X509CertificateBundle leaf_bundle(leaf_certificate_path, EncodingFormat::PEM); + + X509CertificateHierarchy hierarchy = + std::move(X509CertificateHierarchy::build_hierarchy(root_bundle.split(), leaf_bundle.split())); + + fs::path leaf_ocsp = leaf_certificate_path / "ocsp"; + fs::path root_ocsp = ca_bundle_path_map[load] / "ocsp"; + + // Iterate all hashes folders and see if any are missing + for (auto& ocsp_dir : {leaf_ocsp, root_ocsp}) { + if (fs::exists(ocsp_dir)) { + for (auto& ocsp_entry : fs::directory_iterator(ocsp_dir)) { + if (ocsp_entry.is_regular_file() == false) { + continue; + } + + // Attempt hash read + CertificateHashData read_hash; + + if (filesystem_utils::read_hash_from_file(ocsp_entry.path(), read_hash)) { + // If we can't find the has, it means it was deleted somehow, add to delete list + if (hierarchy.contains_certificate_hash(read_hash) == false) { + auto oscp_data_path = ocsp_entry.path(); + oscp_data_path.replace_extension(DER_EXTENSION); + + invalid_ocsp_files.emplace(ocsp_entry.path()); + invalid_ocsp_files.emplace(oscp_data_path); + } + } + } + } + } + } catch (const CertificateLoadException& e) { + EVLOG_warning << "Could not load ca bundle from file: " << leaf_certificate_path; + } + } + + for (const auto& invalid_ocsp : invalid_ocsp_files) { + if (filesystem_utils::delete_file(invalid_ocsp)) + EVLOG_info << "Deleted invalid ocsp file: " << invalid_ocsp; + else + EVLOG_warning << "Error deleting invalid ocsp file: " << invalid_ocsp; + } } bool EvseSecurity::is_filesystem_full() {