Skip to content

Shared storage infrastructure and provider capability routing for certificate management - #160

Open
ChansAlive wants to merge 18 commits into
eclipse-score:mainfrom
etas-contrib:feature/cert_api_and_common_refactor
Open

ChansAlive wants to merge 18 commits into
eclipse-score:mainfrom
etas-contrib:feature/cert_api_and_common_refactor

Conversation

@ChansAlive

@ChansAlive ChansAlive commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Foundational groundwork for the certificate management daemon component.

  • Shared deployment storage (daemon/common/storage/) extracted from key_management — reusable KV loader/writer and atomic file I/O primitives backed by score::filesystem baselibs.
  • Provider capability selection extended to route certificate context types to the correct provider (software-first for kCertManagement).
  • Certificate API types and contexts promoted from api/future/ to stable namespaces.

Closes #162

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run --lockfile_mode=error //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.6.0) and connecting to it...
INFO: Invocation ID: bb3823a8-8abe-4b5d-a675-3411d4c41528
Computing main repo mapping: 
Computing main repo mapping: 
DEBUG: Rule 'score_baselibs_rust+' indicated that a canonical reproducible form can be obtained by modifying arguments integrity = "sha256-4kzcXcvGi9xBEEnrPOiSEvteITZMPKmK3MNgJXQIGtY="
DEBUG: Repository score_baselibs_rust+ instantiated at:
  <builtin>: in <toplevel>
Repository rule http_archive defined at:
  /home/runner/.bazel/external/bazel_tools/tools/build_defs/repo/http.bzl:431:31: in <toplevel>
DEBUG: Rule 'score_logging+' indicated that a canonical reproducible form can be obtained by modifying arguments integrity = "sha256-/Q5+YfLkbMpz5PfvOkNS7qA3ehzth4emFhTcsk4q3zQ="
DEBUG: Repository score_logging+ instantiated at:
  <builtin>: in <toplevel>
Repository rule http_archive defined at:
  /home/runner/.bazel/external/bazel_tools/tools/build_defs/repo/http.bzl:431:31: in <toplevel>
DEBUG: Rule 'abseil-cpp+' indicated that a canonical reproducible form can be obtained by modifying arguments integrity = "sha256-m3oGQwXp/ZTRJP+mzDWFkutCtdpYj7TgfQklSqQAhts="
DEBUG: Repository abseil-cpp+ instantiated at:
  <builtin>: in <toplevel>
Repository rule http_archive defined at:
  /home/runner/.bazel/external/bazel_tools/tools/build_defs/repo/http.bzl:431:31: in <toplevel>
Computing main repo mapping: 
DEBUG: Rule 'grpc+' indicated that a canonical reproducible form can be obtained by modifying arguments integrity = "sha256-CvN7gAlTEwtHwHW1ZoPuYL3D7aPDf8YAQZP1tWl1ggQ="
DEBUG: Repository grpc+ instantiated at:
  <builtin>: in <toplevel>
Repository rule http_archive defined at:
  /home/runner/.bazel/external/bazel_tools/tools/build_defs/repo/http.bzl:431:31: in <toplevel>
Computing main repo mapping: 
DEBUG: Rule 'protobuf+' indicated that a canonical reproducible form can be obtained by modifying arguments integrity = "sha256-w6Cp7OiTLjHDtzbi2xixxC5wcM2biBOIsm0BqnHiTKI="
DEBUG: Repository protobuf+ instantiated at:
  <builtin>: in <toplevel>
Repository rule http_archive defined at:
  /home/runner/.bazel/external/bazel_tools/tools/build_defs/repo/http.bzl:431:31: in <toplevel>
Computing main repo mapping: 
Loading: 
Loading: 1 packages loaded
Loading: 1 packages loaded
    currently loading: 
Loading: 1 packages loaded
    currently loading: 
Loading: 1 packages loaded
    currently loading: 
WARNING: Target pattern parsing failed.
ERROR: Skipping '//:license-check': no such target '//:license-check': target 'license-check' not declared in package '' defined by /home/runner/work/inc_security_crypto/inc_security_crypto/BUILD
ERROR: no such target '//:license-check': target 'license-check' not declared in package '' defined by /home/runner/work/inc_security_crypto/inc_security_crypto/BUILD
INFO: Elapsed time: 12.874s
INFO: 0 processes.
ERROR: Build did NOT complete successfully
ERROR: Build failed. Not running target

@github-actions

Copy link
Copy Markdown
Contributor

The created documentation from the pull request is available at: docu-html

@ChansAlive
ChansAlive force-pushed the feature/cert_api_and_common_refactor branch from d8c0760 to 3806c91 Compare August 13, 2026 20:40
@ChansAlive
ChansAlive marked this pull request as ready for review August 14, 2026 10:24
@ChansAlive
ChansAlive requested a review from sunildevda August 14, 2026 10:25
@ChansAlive
ChansAlive force-pushed the feature/cert_api_and_common_refactor branch from a425c7b to 60c98d8 Compare August 19, 2026 07:31
@ChansAlive
ChansAlive force-pushed the feature/cert_api_and_common_refactor branch from a0b9c2c to 186e256 Compare August 24, 2026 21:10
@ChansAlive
ChansAlive force-pushed the feature/cert_api_and_common_refactor branch from 03e9354 to 9d4bc98 Compare August 25, 2026 11:08
@ChansAlive
ChansAlive force-pushed the feature/cert_api_and_common_refactor branch from 9d4bc98 to cee8b32 Compare August 25, 2026 11:27

load("@rules_cc//cc:defs.bzl", "cc_library")

cc_library(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cert_types.hpp is pure enums. i_ocsp_request_export.hpp is a polymorphic interface and bundling them under one target named cert_types:
Forces every consumer of the enums (lightweight, stable) to also depend on the interface (heavier, unstable/inactive), inflating the rebuild graph for unrelated changes.
split into two cc_library targets (cert_types for enums, i_ocsp_request_export for the interface)

/// @brief Removes the CRL stored in a certificate slot.
/// @param cert_slot Handle to the slot whose CRL should be removed (type = kCertSlot)
/// @return std::monostate on success, error if no CRL is present or access is denied
virtual score::Result<std::monostate> DeleteCrl(const CryptoResourceId& cert_slot) = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeleteExpiredCrls of batch expired CRLs method is removed without replacement

/// @param issuer_cert Handle to the issuer certificate (type = kCertSlot or kCertificate)
/// @param persist When true, store permanently to the issuer slot (kCertSlot only)
/// @return std::monostate on success, error if validation fails or access is denied
virtual score::Result<std::monostate> ImportCrl(score::cpp::span<const uint8_t> crl_data,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you call a function through a base-class pointer/reference, C++ decides which default value to use by looking at the declared type of the variable, not the actual object it points to example persist = false

example:
`class Base
{
public:
virtual void Foo(bool flag = false) = 0;
};

class Derived : public Base
{
public:
void Foo(bool flag = true) override { /* ... */ } // legal, but dangerous
};

Derived d;
Base& b = d;

d.Foo(); // uses Derived's default is flag = true
b.Foo(); // uses Base's default is flag = false (SAME object, DIFFERENT behavior!)`

/// @param cert CryptoResourceId of the certificate to save (type = kCertificate or kCertSlot)
/// @param target_slot Handle to the target slot (type = kCertSlot)
/// @param with_crl When true, propagate the associated CRL to the destination slot
virtual score::Result<std::monostate> SaveCertificate(const CryptoResourceId& cert,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Managing one certificate" (parse/save/export) and "curating the trust anchor set" (add/remove/enable/disable members) are two different concerns, we need to split the interfaces into the smaller chucks. we shall follow the Single Responsibility Principle

/// @brief References an imported CRL for revocation checking.
/// @param crl Handle to a previously imported CRL
/// @return std::monostate on success, error if handle is invalid
virtual score::Result<std::monostate> SetCrl(const CryptoResourceId& crl) = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SetCrl() was deleted, so you can no longer tell the system exactly which revocation list to use — it now guesses automatically, with no documentation on how, and no way to check afterward which one it actually used.

///
/// Each entry corresponds to a certificate slot that currently holds a certificate.
/// Empty slots (not yet populated) are omitted.
virtual const std::vector<MemberInfo>& GetMembers() const noexcept = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetMembers() returns a snapshot that can go stale. if a compromised trust anchor is disabled or removed elsewhere while your code still holds an older snapshot, it will keep reporting that anchor as trusted/enabled. There's no version marker or refresh method to detect this, so code should always re-fetch a fresh snapshot before using it for any actual trust decision, not just for display/logging.

}
const std::string key = Trim(trimmed.substr(0U, eq_pos));
const std::string value = Trim(trimmed.substr(eq_pos + 1U));
descriptor.sections[current_section][key] = value;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate keys are silently overwritten. for example [key_slots]
slot_1 = /secure/path/a.key
slot_1 = /tmp/attacker_path.key

std::unordered_map<std::string, std::unordered_map<std::string, std::string>> sections;

/// @brief Get a value from a section, returning default_val if absent.
[[nodiscard]] const std::string& Get(const std::string& section,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the section/key isn't found, this returns a reference to the default_val parameter. That's only safe if the caller passes a named object that outlives the call. The most natural calling pattern — passing a string literal as the default. for example const std::string& path = descriptor.Get("key_slots", "slot_1", "/default/path");
// path is dangling here — the literal's temporary was destroyed

bool FileExists(const std::string& path)
{
score::filesystem::StandardFilesystem fs{};
const auto result = fs.IsRegularFile(score::filesystem::Path{path});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to handle the permissions related issues, actual file present but no access

else if (required_capability != common::ProviderCapability::kNone &&
requested_provider_type == common::CryptoProviderType::DEFAULT)
{
provider = m_provider_manager->GetProviderForCapability(required_capability);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the else branch the provider capablity is not checked, so it will fail on create handler with unsupported algo

@ChansAlive
ChansAlive force-pushed the feature/cert_api_and_common_refactor branch from 99970fa to 51f6130 Compare September 10, 2026 20:10
@ChansAlive
ChansAlive force-pushed the feature/cert_api_and_common_refactor branch from 51f6130 to a01368f Compare September 11, 2026 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cert API and Daemon refactoring for cert management

2 participants